diff --git a/crowdin.yml b/crowdin.yml index fdcb6bcd32d..04cbe1a8d50 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,6 +1,5 @@ files: - - source: /public/locale/{{lang}}.json - translation: /public/locale/%two_letters_code%/%original_file_name% + - source: public/locale/en.json + translation: /public/locale/%two_letters_code%.json bundles: - 2 - diff --git a/public/locale/en.json b/public/locale/en.json index 32cdc9c221c..3fbcfc3de72 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -359,6 +359,7 @@ "all_changes_have_been_saved": "All changes have been saved", "all_details": "All Details", "all_patients": "All Patients", + "allergen": "Allergen", "allergies": "Allergies", "allow_transfer": "Allow Transfer", "allowed_formats_are": "Allowed formats are", @@ -650,6 +651,7 @@ "created_by": "Created By", "created_date": "Created Date", "created_on": "Created On", + "criticality": "Criticality", "csv_file_in_the_specified_format": "Select a CSV file in the specified format", "current_address": "Current Address", "current_password": "Current Password", @@ -829,6 +831,7 @@ "encounter_discharge_disposition__snf": "Skilled nursing facility", "encounter_duration_confirmation": "The duration of this encounter would be", "encounter_id": "Encounter ID", + "encounter_marked_as_complete": "Encounter Completed", "encounter_notes__all_discussions": "All Discussions", "encounter_notes__be_first_to_send": "Be the first to send a message", "encounter_notes__choose_template": "Choose a template or enter a custom title", @@ -899,6 +902,7 @@ "error_deleting_shifting": "Error while deleting Shifting record", "error_fetching_slots_data": "Error while fetching slots data", "error_sending_otp": "Error while sending OTP, Please try again later", + "error_updating_encounter": "Error to Updating Encounter", "error_verifying_otp": "Error while verifying OTP, Please request a new OTP", "error_while_deleting_record": "Error while deleting record", "escape": "Escape", @@ -1163,6 +1167,7 @@ "manufacturer": "Manufacturer", "map_acronym": "M.A.P.", "mark_all_as_read": "Mark all as Read", + "mark_as_complete": "Mark as Complete", "mark_as_fulfilled": "Mark as Fullfilled", "mark_as_noshow": "Mark as no-show", "mark_as_read": "Mark as Read", @@ -1627,6 +1632,7 @@ "select": "Select", "select_all": "Select All", "select_date": "Select date", + "select_department": "Select Department", "select_eligible_policy": "Select an Eligible Insurance Policy", "select_facility_for_discharged_patients_warning": "Facility needs to be selected to view discharged patients.", "select_for_administration": "Select for Administration", diff --git a/src/Routers/PatientRouter.tsx b/src/Routers/PatientRouter.tsx index 99deda2f3a7..bf16c8c3e30 100644 --- a/src/Routers/PatientRouter.tsx +++ b/src/Routers/PatientRouter.tsx @@ -2,7 +2,7 @@ import careConfig from "@careConfig"; import { useRoutes } from "raviger"; import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar"; -import { AppSidebar } from "@/components/ui/sidebar/app-sidebar"; +import { AppSidebar, SidebarFor } from "@/components/ui/sidebar/app-sidebar"; import ErrorBoundary from "@/components/Common/ErrorBoundary"; import ErrorPage from "@/components/ErrorPages/DefaultErrorPage"; @@ -78,7 +78,7 @@ export default function PatientRouter() { return ( - +
), - "/facility/:facilityId/patient/:patientId/consultation/:id/consent-records": - ({ facilityId, patientId, id }) => ( - - ), - "/facility/:facilityId/patient/:patientId/encounterId/:id/files/": ({ - facilityId, - patientId, - id, - }) => ( - - ), "/facility/:facilityId/patient/:patientId/questionnaire": ({ facilityId, patientId, @@ -80,10 +60,6 @@ const consultationRoutes: AppRoutes = { patientId={patientId} /> ), - "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire_response/:id": - ({ patientId, id }) => ( - - ), "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire/:slug": ({ facilityId, encounterId, slug, patientId }) => ( ), + "/facility/:facilityId/patient/:patientId/encounter/:encounterId/questionnaire_response/:id": + ({ patientId, id }) => ( + + ), + "/facility/:facilityId/patient/:patientId/consultation/:id/consent-records": + ({ facilityId, patientId, id }) => ( + + ), + "/facility/:facilityId/patient/:patientId/encounterId/:id/files/": ({ + facilityId, + patientId, + id, + }) => ( + + ), }; export default consultationRoutes; diff --git a/src/components/Patient/PatientInfoCard.tsx b/src/components/Patient/PatientInfoCard.tsx index 8c0c8d29014..2c716095400 100644 --- a/src/components/Patient/PatientInfoCard.tsx +++ b/src/components/Patient/PatientInfoCard.tsx @@ -1,3 +1,4 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; import { BedSingle, Building, @@ -9,8 +10,18 @@ import { } from "lucide-react"; import { Link } from "raviger"; import { useTranslation } from "react-i18next"; +import { toast } from "sonner"; import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; import { Popover, PopoverContent, @@ -19,13 +30,29 @@ import { import { Avatar } from "@/components/Common/Avatar"; +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 { Button } from "../ui/button"; import ManageEncounterOrganizations from "./ManageEncounterOrganizations"; +const QUESTIONNAIRE_OPTIONS = [ + { + slug: "encounter", + title: "Update Encounter", + }, + { + slug: "community-nurse", + title: "Community Nurse Form", + }, + { + slug: "recommend_discharge_v2", + title: "Recommend Discharge", + }, +] as const; + export interface PatientInfoCardProps { patient: Patient; encounter: Encounter; @@ -35,6 +62,36 @@ export interface PatientInfoCardProps { export default function PatientInfoCard(props: PatientInfoCardProps) { const { patient, encounter } = props; const { t } = useTranslation(); + const queryClient = useQueryClient(); + + const { mutate: updateEncounter } = useMutation({ + mutationFn: mutate(routes.encounter.update, { + pathParams: { id: encounter.id }, + }), + onSuccess: () => { + toast.success(t("encounter_marked_as_complete")); + queryClient.invalidateQueries({ queryKey: ["encounter", encounter.id] }); + }, + onError: () => { + toast.error(t("error_updating_encounter")); + }, + }); + + const handleMarkAsComplete = () => { + updateEncounter({ + ...encounter, + status: "completed", + organizations: encounter.organizations.map((org) => org.id), + patient: encounter.patient.id, + encounter_class: encounter.encounter_class, + period: encounter.period, + hospitalization: encounter.hospitalization, + priority: encounter.priority, + external_identifier: encounter.external_identifier, + facility: encounter.facility.id, + }); + }; + return ( <>
@@ -262,13 +319,31 @@ export default function PatientInfoCard(props: PatientInfoCardProps) { > {!completedEncounterStatus.includes(encounter.status) && (
- + + + + + + {QUESTIONNAIRE_OPTIONS.map((option) => ( + + + {t(option.title)} + + + ))} + + {t("actions")} + + {t("mark_as_complete")} + + +
)} diff --git a/src/components/Patient/PatientRegistration.tsx b/src/components/Patient/PatientRegistration.tsx index 1dc236f5fb3..94289124403 100644 --- a/src/components/Patient/PatientRegistration.tsx +++ b/src/components/Patient/PatientRegistration.tsx @@ -8,7 +8,6 @@ import SectionNavigator from "@/CAREUI/misc/SectionNavigator"; import { Button } from "@/components/ui/button"; import { Checkbox } from "@/components/ui/checkbox"; -import { InputErrors } from "@/components/ui/errors"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; @@ -49,7 +48,6 @@ import OrganizationSelector from "@/pages/Organization/components/OrganizationSe import { PatientModel, validatePatient } from "@/types/emr/patient"; import Autocomplete from "../ui/autocomplete"; -import InputWithError from "../ui/input-with-error"; interface PatientRegistrationPageProps { facilityId: string; @@ -316,71 +314,93 @@ export default function PatientRegistration(
{t("general_info_detail")}

- - - + + +
+ {errors["name"] && + errors["name"].map((error, i) => ( +
+ {error} +
+ ))} +

- - { - if (e.target.value.length > 13) return; - setForm((f) => ({ - ...f, - phone_number: e.target.value, - emergency_phone_number: samePhoneNumber - ? e.target.value - : f.emergency_phone_number, - })); + + { + if (e.target.value.length > 13) return; + setForm((f) => ({ + ...f, + phone_number: e.target.value, + emergency_phone_number: samePhoneNumber + ? e.target.value + : f.emergency_phone_number, + })); + }} + /> +
+ {errors["phone_number"] && + errors["phone_number"]?.map((error, i) => ( +
+ {error} +
+ ))} +
+ +
+ { + const newValue = !samePhoneNumber; + setSamePhoneNumber(newValue); + if (newValue) { + setForm((f) => ({ + ...f, + emergency_phone_number: f.phone_number, + })); + } }} + id="same-phone-number" /> - -
- - { - const newValue = !samePhoneNumber; - setSamePhoneNumber(newValue); - if (newValue) { - setForm((f) => ({ - ...f, - emergency_phone_number: f.phone_number, - })); - } - }} - id="same-phone-number" - /> - - +

- - { - if (e.target.value.length > 13) return; - setForm((f) => ({ - ...f, - emergency_phone_number: e.target.value, - })); - }} - disabled={samePhoneNumber} - /> - + + + { + if (e.target.value.length > 13) return; + setForm((f) => ({ + ...f, + emergency_phone_number: e.target.value, + })); + }} + disabled={samePhoneNumber} + /> +
+ {errors["emergency_phone_number"] && + errors["emergency_phone_number"]?.map((error, i) => ( +
+ {error} +
+ ))} +
{/*
*/}
- - - setForm((f) => ({ ...f, gender: value })) - } - className="flex items-center gap-4" - > - {GENDER_TYPES.map((g) => ( - - - - + + + + setForm((f) => ({ ...f, gender: value })) + } + className="flex items-center gap-4" + > + {GENDER_TYPES.map((g) => ( + + + + + ))} + +
+ {errors["gender"] && + errors["gender"]?.map((error, i) => ( +
+ {error} +
))} - - +
+
- - - + + + +
+ {errors["blood_group"] && + errors["blood_group"]?.map((error, i) => ( +
+ {error} +
+ ))} +
+
- - - setForm((f) => ({ - ...f, - date_of_birth: `${form.date_of_birth?.split("-")[0] || ""}-${form.date_of_birth?.split("-")[1] || ""}-${e.target.value}`, - })) - } - /> - + + + setForm((f) => ({ + ...f, + date_of_birth: `${form.date_of_birth?.split("-")[0] || ""}-${form.date_of_birth?.split("-")[1] || ""}-${e.target.value}`, + })) + } + />
- - - setForm((f) => ({ - ...f, - date_of_birth: `${form.date_of_birth?.split("-")[0] || ""}-${e.target.value}-${form.date_of_birth?.split("-")[2] || ""}`, - })) - } - /> - + + + setForm((f) => ({ + ...f, + date_of_birth: `${form.date_of_birth?.split("-")[0] || ""}-${e.target.value}-${form.date_of_birth?.split("-")[2] || ""}`, + })) + } + />
- - - setForm((f) => ({ - ...f, - date_of_birth: `${e.target.value}-${form.date_of_birth?.split("-")[1] || ""}-${form.date_of_birth?.split("-")[2] || ""}`, - })) - } - /> - + + + setForm((f) => ({ + ...f, + date_of_birth: `${e.target.value}-${form.date_of_birth?.split("-")[1] || ""}-${form.date_of_birth?.split("-")[2] || ""}`, + })) + } + />
{errors["date_of_birth"] && ( - +
+ {errors["date_of_birth"].map((error, i) => ( +
+ {error} +
+ ))} +
)} @@ -512,25 +564,32 @@ export default function PatientRegistration( {t("age_input_warning_bold")}
- - - setForm((f) => ({ - ...f, - age: e.target.value, - year_of_birth: e.target.value - ? new Date().getFullYear() - Number(e.target.value) - : undefined, - })) - } - type="number" - /> - + + + setForm((f) => ({ + ...f, + age: e.target.value, + year_of_birth: e.target.value + ? new Date().getFullYear() - Number(e.target.value) + : undefined, + })) + } + type="number" + /> +
+ {errors["year_of_birth"] && + errors["year_of_birth"]?.map((error, i) => ( +
+ {error} +
+ ))} +
+ {form.year_of_birth && (
{t("year_of_birth")} : {form.year_of_birth} @@ -540,68 +599,84 @@ export default function PatientRegistration(
- -