Skip to content

Commit

Permalink
Encounter overview and sidebar Redesign (#10440)
Browse files Browse the repository at this point in the history
  • Loading branch information
amjithtitus09 authored Feb 6, 2025
1 parent 6bc04d7 commit 85866da
Show file tree
Hide file tree
Showing 15 changed files with 924 additions and 360 deletions.
35 changes: 34 additions & 1 deletion public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@
"add_notes": "Add notes",
"add_notes_about_diagnosis": "Add notes about the diagnosis...",
"add_notes_about_symptom": "Add notes about the symptom...",
"add_notes_about_the_allergy": "Add notes about the allergy",
"add_organizations": "Add Organizations",
"add_patient_updates": "Add Patient Updates",
"add_policy": "Add Insurance Policy",
Expand Down Expand Up @@ -492,6 +493,7 @@
"cannot_select_year_out_of_range": "Cannot select year out of range",
"capture": "Capture",
"card": "Card",
"cardiology": "Cardiology",
"care": "CARE",
"care_backend": "Care Backend",
"care_frontend": "Care Frontend",
Expand Down Expand Up @@ -582,7 +584,9 @@
"confirm_transfer_complete": "Confirm Transfer Complete!",
"confirm_unavailability": "Confirm Unavailability",
"confirmed": "Confirmed",
"consent_form": "Consent Form",
"consult": "Consult",
"consultation": "Consultation",
"consultation_history": "Consultation History",
"consultation_missing_warning": "You have not created a consultation for the patient in",
"consultation_not_filed": "You have not filed a consultation for this patient yet.",
Expand Down Expand Up @@ -690,6 +694,7 @@
"demography": "Demography",
"denied_on": "Denied On",
"departments": "Departments",
"departments_and_teams": "Departments and Teams",
"describe_why_the_asset_is_not_working": "Describe why the asset is not working",
"description": "Description",
"details_about_the_equipment": "Details about the equipment",
Expand Down Expand Up @@ -724,6 +729,7 @@
"discharged_on": "Discharged On",
"discharged_patients": "Discharged Patients",
"discharged_patients_empty": "No discharged patients present in this facility",
"discharged_to": "Discharged to",
"disclaimer": "Disclaimer",
"discontinue": "Discontinue",
"discontinue_caution_note": "Are you sure you want to discontinue this prescription?",
Expand All @@ -742,6 +748,7 @@
"doctor_nurse": "Doctor/Nurse",
"doctor_s_medical_council_registration": "Doctor's Medical Council Registration",
"doctors_name": "Doctor's Name",
"doctors_progress_note": "Doctor's Progress Note",
"domestic_healthcare_support": "Domestic healthcare support",
"domestic_international_travel": "Domestic/international Travel (within last 28 days)",
"done": "Done",
Expand Down Expand Up @@ -885,6 +892,9 @@
"encounter_priority__timing_critical": "Timing critical",
"encounter_priority__urgent": "Urgent",
"encounter_priority__use_as_directed": "Use as directed",
"encounter_re_admission__false": "No",
"encounter_re_admission__true": "Yes",
"encounter_settings": "Encounter Settings",
"encounter_status": "Encounter Status",
"encounter_status__cancelled": "Cancelled",
"encounter_status__completed": "Completed",
Expand Down Expand Up @@ -981,6 +991,7 @@
"facility_updated_successfully": "Facility updated successfully",
"failed_to_create_appointment": "Failed to create an appointment",
"failed_to_link_abha_number": "Failed to link ABHA Number. Please try again later.",
"false": "False",
"fast_track_testing_reason": "Fast track testing reason",
"features": "Features",
"feed_configurations": "Feed Configurations",
Expand Down Expand Up @@ -1029,6 +1040,7 @@
"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.",
"forms": "Forms",
"frequency": "Frequency",
"from": "from",
"from_date_must_be_before_to_date": "From date must be before to date",
Expand Down Expand Up @@ -1078,6 +1090,7 @@
"home_facility_updated_error": "Error while updating Home Facility",
"home_facility_updated_success": "Home Facility updated successfully",
"hospital_identifier": "Hospital Identifier",
"hospitalisation_details": "Hospitalization Details",
"hospitalization_details": "Hospitalization Details",
"hubs": "Hub Facilities",
"i_declare": "I hereby declare that:",
Expand Down Expand Up @@ -1225,6 +1238,7 @@
"log_report": "Log Report",
"log_update": "Log Update",
"log_updates": "Log Updates",
"logged_by": "Logged by",
"logged_in_as": "Logged in as",
"login": "Login",
"logout": "Log Out",
Expand All @@ -1247,13 +1261,16 @@
"manage_user": "Manage User",
"manufacturer": "Manufacturer",
"map_acronym": "M.A.P.",
"mark_active": "Mark Active",
"mark_all_as_read": "Mark all as Read",
"mark_as_complete": "Mark as Complete",
"mark_as_entered_in_error": "Mark as entered in error",
"mark_as_fulfilled": "Mark as Fullfilled",
"mark_as_noshow": "Mark as no-show",
"mark_as_read": "Mark as Read",
"mark_as_unread": "Mark as Unread",
"mark_inactive": "Mark Inactive",
"mark_resolved": "Mark Resolved",
"mark_this_transfer_as_complete_question": "Are you sure you want to mark this transfer as complete? The Origin facility will no longer have access to this patient",
"mark_transfer_complete_confirmation": "Are you sure you want to mark this transfer as complete? The Origin facility will no longer have access to this patient",
"markdown_supported": "You can use markdown to format your facility description",
Expand Down Expand Up @@ -1435,12 +1452,16 @@
"number_of_chronic_diseased_dependents": "Number Of Chronic Diseased Dependents",
"number_of_covid_vaccine_doses": "Number of Covid vaccine doses",
"nurse": "Nurse",
"nurses_form": "Nurse's Form",
"nursing_care": "Nursing Care",
"nursing_home": "Nursing Home",
"nursing_information": "Nursing Information",
"nutrition": "Nutrition",
"observations": "Observations",
"occupancy": "Occupancy",
"occupation": "Occupation",
"occupied": "Occupied",
"occurrence": "Occurrence",
"old_password": "Current Password",
"on": "on",
"on_emergency_basis": " on emergency basis",
Expand Down Expand Up @@ -1669,12 +1690,14 @@
"questionnaire_not_exist": "The questionnaire you tried to access does not exist.",
"questionnaire_submission_failed": "Failed to submit questionnaire",
"questionnaire_submitted_successfully": "Questionnaire submitted successfully",
"quick_access": "Quick Access",
"quick_actions": "Quick Actions",
"quick_actions_description": "Schedule an appointment or create a new encounter",
"ration_card__APL": "APL",
"ration_card__BPL": "BPL",
"ration_card__NO_CARD": "Non-card holder",
"ration_card_category": "Ration Card Category",
"re_admission": "Re-Admission",
"readmission": "Re-admission",
"reason": "Reason",
"reason_for_discontinuation": "Reason for discontinuation",
Expand All @@ -1685,6 +1708,7 @@
"reason_for_shift": "Reason for shift",
"reason_for_visit": "Reason for visit",
"reason_for_visit_placeholder": "Type the reason for booking appointment",
"recommend_discharge": "Recommend Discharge",
"recommended_aspect_ratio_for": "Recommended aspect ratio for the image is {{aspectRatio}}.",
"record": "Record Audio",
"record_delete_confirm": "Are you sure you want to delete this record?",
Expand All @@ -1711,6 +1735,7 @@
"remarks_placeholder": "Enter remarks",
"remission": "Remission",
"remove": "Remove",
"remove_allergy": "Remove Allergy",
"remove_diagnosis": "Remove Diagnosis",
"remove_medication": "Remove Medication",
"remove_medication_confirmation": "Are you sure you want to remove {{medication}}?",
Expand Down Expand Up @@ -1776,6 +1801,7 @@
"resource_status__transportation_to_be_arranged": "Transportation to be arranged",
"resource_title": "Resource Title",
"resource_type": "Request Type",
"respiratory_status": "Respiratory Status",
"result": "Result",
"result_date": "Result Date",
"result_details": "Result details",
Expand Down Expand Up @@ -1849,6 +1875,7 @@
"search_by_username": "Search by username",
"search_country": "Search country...",
"search_encounters": "Search Encounters",
"search_for_allergies_to_add": "Search for allergies to add",
"search_for_diagnoses_to_add": "Search for diagnoses to add",
"search_for_facility": "Search for Facility",
"search_for_symptoms_to_add": "Search for symptoms to add",
Expand All @@ -1865,6 +1892,7 @@
"search_user_description": "Search for a user and assign a role to add them to the patient.",
"searching": "Searching...",
"see_attachments": "See Attachments",
"see_note": "See Note",
"select": "Select",
"select_additional_instructions": "Select additional instructions",
"select_admit_source": "Select Admit Source",
Expand Down Expand Up @@ -2035,6 +2063,7 @@
"tachycardia": "Tachycardia",
"tag_name": "Tag Name",
"tag_slug": "Tag Slug",
"tags": "Tags",
"taken": "Taken",
"taper_titrate_dosage": "Taper & Titrate Dosage",
"target_dosage": "Target Dosage",
Expand Down Expand Up @@ -2076,6 +2105,7 @@
"treatment_summary__heading": "INTERIM TREATMENT SUMMARY",
"treatment_summary__print": "Print Treatment Summary",
"triage_category": "Triage Category",
"true": "True",
"try_again_later": "Try again later!",
"try_different_abha_linking_option": "Want to try a different linking option, here are some more:",
"type_any_extra_comments_here": "type any extra comments here",
Expand Down Expand Up @@ -2142,9 +2172,12 @@
"update_asset_service_record": "Update Asset Service Record",
"update_available": "Update Available",
"update_bed": "Update Bed",
"update_department": "Update Department",
"update_encounter_details": "Update Encounter Details",
"update_existing_facility": "Update the details of the existing facility.",
"update_facility": "Update Facility",
"update_facility_middleware_success": "Facility middleware updated successfully",
"update_hospitalisation_details": "Update Hospitalisation Details",
"update_log": "Update Log",
"update_password": "Update Password",
"update_patient_details": "Update Patient Details",
Expand Down Expand Up @@ -2239,7 +2272,7 @@
"video_conference_link": "Video Conference Link",
"view": "View",
"view_abdm_records": "View ABDM Records",
"view_all": "view all",
"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
134 changes: 106 additions & 28 deletions src/components/Facility/ConsultationDetails/ObservationsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useInView } from "react-intersection-observer";

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

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

import { formatValue } from "@/components/Facility/ConsultationDetails/QuestionnaireResponsesList";
Expand All @@ -13,7 +11,6 @@ import routes from "@/Utils/request/api";
import query from "@/Utils/request/query";
import { HTTPError } from "@/Utils/request/types";
import { PaginatedResponse } from "@/Utils/request/types";
import { formatDateTime } from "@/Utils/utils";
import { Encounter } from "@/types/emr/encounter";
import { Observation } from "@/types/emr/observation";

Expand All @@ -23,6 +20,59 @@ interface Props {
encounter: Encounter;
}

interface GroupedObservations {
[key: string]: Observation[];
}

function getDateKey(date: string) {
return new Date(date).toISOString().split("T")[0];
}

function formatDisplayDate(dateStr: string) {
const date = new Date(dateStr);
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);

// Reset time parts for accurate date comparison
today.setHours(0, 0, 0, 0);
yesterday.setHours(0, 0, 0, 0);
date.setHours(0, 0, 0, 0);

const formattedDate = date.toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
});

if (date.getTime() === today.getTime()) {
return `Today (${formattedDate})`;
} else if (date.getTime() === yesterday.getTime()) {
return `Yesterday (${formattedDate})`;
}
return formattedDate;
}

function formatDisplayTime(dateStr: string) {
return new Date(dateStr).toLocaleTimeString("en-US", {
hour: "2-digit",
minute: "2-digit",
});
}

function groupObservationsByDate(
observations: Observation[],
): GroupedObservations {
return observations.reduce((groups: GroupedObservations, observation) => {
const dateKey = getDateKey(observation.effective_datetime);
if (!groups[dateKey]) {
groups[dateKey] = [];
}
groups[dateKey].push(observation);
return groups;
}, {});
}

export default function ObservationsList(props: Props) {
const { t } = useTranslation();
const patientId = props.encounter.patient.id;
Expand Down Expand Up @@ -77,35 +127,63 @@ export default function ObservationsList(props: Props) {
);
}

const groupedObservations = groupObservationsByDate(observations);
const dates = Object.keys(groupedObservations).sort().reverse();

return (
<div className="mt-4 flex w-full flex-col gap-4">
<div className="flex max-h-[85vh] flex-col gap-4 overflow-y-auto overflow-x-hidden px-3">
{observations.map((item: Observation) => (
<Card key={item.id} className="flex items-center justify-between p-4">
<div>
<div className="text-xs flex items-center gap-1 text-gray-500">
<CareIcon icon="l-calender" />
<span>{formatDateTime(item.effective_datetime)}</span>
</div>
<div className="font-medium">
{item.main_code.display || item.main_code.code}
</div>
{item.value.value_quantity && (
<div className="mt-1 font-medium">
{item.value.value_quantity.value}{" "}
{item.value.value_quantity.code.display}
</div>
)}
{item.value.value && (
<div className="mt-1 font-medium whitespace-pre-wrap">
{formatValue(item.value.value, item.value_type)}
</div>
)}
{item.note && (
<div className="mt-1 text-sm text-gray-500">{item.note}</div>
)}
{dates.map((date, index) => (
<div key={date}>
<div className="mb-3 text-base font-semibold text-gray-700">
{formatDisplayDate(date)}
</div>
</Card>
<div className="flex flex-col gap-3">
{groupedObservations[date]
.sort(
(a, b) =>
new Date(b.effective_datetime).getTime() -
new Date(a.effective_datetime).getTime(),
)
.map((item: Observation) => (
<div key={item.id} className="flex gap-4">
<div className="p-1 h-fit text-sm text-gray-700 bg-gray-100 rounded-md font-medium">
{formatDisplayTime(item.effective_datetime)}:
</div>
<Card className="flex-1 p-3 border-gray-100 shadow-none bg-gray-50">
<div>
<div className="flex items-center gap-2">
{item.value.value && (
<div className="mt-1 font-semibold whitespace-pre-wrap text-lg text-gray-950">
{formatValue(item.value.value, item.value_type)}
</div>
)}
{item.value.value_quantity && (
<div className="mt-1 font-medium">
{item.value.value_quantity.value}{" "}
<div className="text-xs text-gray-600">
{item.value.value_quantity.code.display}
</div>
</div>
)}
</div>
{item.note && (
<div className="mt-1 text-sm text-gray-500">
{item.note}
</div>
)}
<div className="font-medium text-sm text-gray-600">
{item.main_code.display || item.main_code.code}
</div>
</div>
</Card>
</div>
))}
</div>
{index < dates.length - 1 && (
<div className="my-4 border-b border-dashed border-gray-200" />
)}
</div>
))}
{hasNextPage && (
<div ref={ref} className="flex justify-center p-4">
Expand Down
Loading

0 comments on commit 85866da

Please sign in to comment.