diff --git a/cypress/e2e/assets_spec/AssetsCreation.cy.ts b/cypress/e2e/assets_spec/AssetsCreation.cy.ts index 775ddc3a609..1bcd984a7a3 100644 --- a/cypress/e2e/assets_spec/AssetsCreation.cy.ts +++ b/cypress/e2e/assets_spec/AssetsCreation.cy.ts @@ -54,7 +54,7 @@ describe("Asset", () => { "email@support.com", "Vendor's Name", serialNumber, - "25/12/2021", + "25122021", "Test note for asset creation!", ); @@ -77,7 +77,7 @@ describe("Asset", () => { "email@support.com", "Vendor's Name", serialNumber, - "25/12/2021", + "25122021", "Test note for asset creation!", ); @@ -104,7 +104,7 @@ describe("Asset", () => { "Customer Support's Name Edited", "Vendor's Name Edited", "Test note for asset creation edited!", - "25/12/2021", + "25122021", ); assetPage.clickUpdateAsset(); @@ -152,7 +152,7 @@ describe("Asset", () => { "email@support.com", "Vendor's Name", serialNumber, - "25/12/2021", + "25122021", "Test note for asset creation!", ); assetPage.interceptAssetCreation(); diff --git a/cypress/e2e/assets_spec/AssetsManage.cy.ts b/cypress/e2e/assets_spec/AssetsManage.cy.ts index a5a7ddf243c..983a82be07b 100644 --- a/cypress/e2e/assets_spec/AssetsManage.cy.ts +++ b/cypress/e2e/assets_spec/AssetsManage.cy.ts @@ -67,7 +67,7 @@ describe("Asset", () => { assetPage.clickupdatedetailbutton(); assetPage.scrollintonotes(); assetPage.enterAssetNotes("Dummy Notes"); - assetPage.enterAssetservicedate("01/09/2023"); + assetPage.enterAssetservicedate("01092023"); assetPage.clickassetupdatebutton(); assetPage.scrollintoservicehistory(); assetPage.clickedithistorybutton(); diff --git a/cypress/e2e/facility_spec/FacilityCreation.cy.ts b/cypress/e2e/facility_spec/FacilityCreation.cy.ts index a65eca5c69e..918e926d107 100644 --- a/cypress/e2e/facility_spec/FacilityCreation.cy.ts +++ b/cypress/e2e/facility_spec/FacilityCreation.cy.ts @@ -32,7 +32,7 @@ describe("Facility Creation", () => { const facilityAddress = "cypress address"; const facilityUpdateAddress = "cypress updated address"; const facilityNumber = "9898469865"; - const triageDate = "02/12/2023"; + const triageDate = "02122023"; const initialTriageValue = "60"; const modifiedTriageValue = "50"; const facilityErrorMessage = [ diff --git a/cypress/e2e/facility_spec/FacilityLocation.cy.ts b/cypress/e2e/facility_spec/FacilityLocation.cy.ts index ab015e175d6..113a5e3eaab 100644 --- a/cypress/e2e/facility_spec/FacilityLocation.cy.ts +++ b/cypress/e2e/facility_spec/FacilityLocation.cy.ts @@ -247,7 +247,7 @@ describe("Location Management Section", () => { "email@support.com", "Vendor's Name", serialNumber, - "25/12/2021", + "25122021", "Test note for asset creation!", ); assetPage.clickassetupdatebutton(); diff --git a/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts b/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts index d3cc4a52029..9911090eba0 100644 --- a/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts +++ b/cypress/e2e/patient_spec/PatientConsultationCreation.cy.ts @@ -86,7 +86,7 @@ describe("Patient Consultation in multiple combination", () => { patientConsultationPage.selectPatientPrincipalDiagnosis(diagnosis4); patientTreatmentPlan.clickAddProcedure(); patientTreatmentPlan.typeProcedureName(procedureName); - patientTreatmentPlan.typeProcedureTime("22/02/2024 12:30 pm"); + patientTreatmentPlan.typeProcedureTime("220220241230"); patientTreatmentPlan.typeTreatmentPlan(patientTreatment); patientTreatmentPlan.typePatientGeneralInstruction(generalInstruction); patientTreatmentPlan.typeSpecialInstruction(specialInstruction); @@ -182,12 +182,12 @@ describe("Patient Consultation in multiple combination", () => { patientConsultationPage.typeCauseOfDeath("Cause of Death"); patientConsultationPage.typePatientConsultationDate( "#death_datetime", - "22/02/2024 12:30 pm", + "220220241230", ); patientConsultationPage.typeDeathConfirmedBy(doctorName); patientConsultationPage.typePatientConsultationDate( "#encounter_date", - "22/02/2024 12:30 pm", + "220220241230", ); cy.submitButton("Create Consultation"); cy.verifyNotification( @@ -245,7 +245,7 @@ describe("Patient Consultation in multiple combination", () => { ); patientConsultationPage.typePatientConsultationDate( "#icu_admission_date", - "23/02/2024 12:30 pm", + "230220241230", ); // add investigation patientInvestigation.clickAddInvestigation(); @@ -293,7 +293,7 @@ describe("Patient Consultation in multiple combination", () => { ); // verify the free text in referring facility name patientConsultationPage.typeReferringFacility("Life Care Hospital"); - patientConsultationPage.selectSymptomsDate("01/01/2024"); + patientConsultationPage.selectSymptomsDate("01012024"); patientConsultationPage.typeAndMultiSelectSymptoms("s", [ "Sore throat", "Sputum", @@ -338,7 +338,7 @@ describe("Patient Consultation in multiple combination", () => { "Outpatient/Emergency Room", ); // Select the Symptoms - Breathlessness and Bleeding symptoms - patientConsultationPage.selectSymptomsDate("01/01/2024"); + patientConsultationPage.selectSymptomsDate("01012024"); patientConsultationPage.typeAndMultiSelectSymptoms("b", [ "Breathlessness", "Bleeding", diff --git a/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts b/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts index c49fb5bf08d..7faaeed5a9f 100644 --- a/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts +++ b/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts @@ -238,7 +238,7 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { patientLogupdate.typePhysicalExamination(physicalExamination); patientLogupdate.selectPatientCategory(patientCategory); patientLogupdate.typeOtherDetails(otherExamination); - patientLogupdate.selectSymptomsDate("01/01/2024"); + patientLogupdate.selectSymptomsDate("01012024"); patientLogupdate.typeAndMultiSelectSymptoms("fe", ["Fever"]); patientLogupdate.clickAddSymptom(); patientLogupdate.typeSystolic(patientSystolic); @@ -268,7 +268,7 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => { patientLogupdate.clickLogupdate(); patientLogupdate.typePhysicalExamination(physicalExamination); patientLogupdate.typeOtherDetails(otherExamination); - patientLogupdate.selectSymptomsDate("01/01/2024"); + patientLogupdate.selectSymptomsDate("01012024"); patientLogupdate.typeAndMultiSelectSymptoms("fe", ["Fever"]); patientLogupdate.selectPatientCategory(patientCategory); patientLogupdate.typeSystolic(patientSystolic); diff --git a/cypress/e2e/patient_spec/PatientRegistration.cy.ts b/cypress/e2e/patient_spec/PatientRegistration.cy.ts index 7a459603b2e..26adc7c882b 100644 --- a/cypress/e2e/patient_spec/PatientRegistration.cy.ts +++ b/cypress/e2e/patient_spec/PatientRegistration.cy.ts @@ -19,11 +19,13 @@ const getRelativeDateString = (deltaDays = 0) => { if (deltaDays) { date.setDate(date.getDate() + deltaDays); } - return date.toLocaleDateString("en-IN", { - day: "2-digit", - month: "2-digit", - year: "numeric", - }); + return date + .toLocaleDateString("en-IN", { + day: "2-digit", + month: "2-digit", + year: "numeric", + }) + .replace("/", ""); }; describe("Patient Creation with consultation", () => { diff --git a/cypress/e2e/users_spec/UsersCreation.cy.ts b/cypress/e2e/users_spec/UsersCreation.cy.ts index 72ce426e805..0c0286e795e 100644 --- a/cypress/e2e/users_spec/UsersCreation.cy.ts +++ b/cypress/e2e/users_spec/UsersCreation.cy.ts @@ -90,7 +90,7 @@ describe("User Creation", () => { userCreationPage.typeIntoElementByIdPostClear("weekly_working_hours", "14"); userCreationPage.typeIntoElementByIdPostClearDob( "date_of_birth", - "01/01/1998", + "01011998", ); userCreationPage.clickElementById("submit"); userCreationPage.verifyElementContainsText( @@ -146,7 +146,7 @@ describe("User Creation", () => { userCreationPage.typeIntoElementById("password", "Test@123"); userCreationPage.selectHomeFacility("Dummy Shifting Center"); userCreationPage.typeIntoElementById("phone_number", phone_number); - userCreationPage.setInputDate("date_of_birth", "date-input", "25/08/1999"); + userCreationPage.setInputDate("date_of_birth", "25081999"); userCreationPage.selectDropdownOption("user_type", "Doctor"); userCreationPage.typeIntoElementById("c_password", "Test@123"); userCreationPage.typeIntoElementById("qualification", "MBBS"); diff --git a/cypress/e2e/users_spec/user_profile.cy.ts b/cypress/e2e/users_spec/user_profile.cy.ts deleted file mode 100644 index 787853c5a79..00000000000 --- a/cypress/e2e/users_spec/user_profile.cy.ts +++ /dev/null @@ -1,82 +0,0 @@ -import LoginPage from "../../pageobject/Login/LoginPage"; -import UserProfilePage from "../../pageobject/Users/UserProfilePage"; -import ManageUserPage from "../../pageobject/Users/ManageUserPage"; - -describe("Manage User Profile", () => { - const loginPage = new LoginPage(); - const userProfilePage = new UserProfilePage(); - const manageUserPage = new ManageUserPage(); - - const date_of_birth = "01/01/1999"; - const gender = "Male"; - const email = "test@example.com"; - const phone = "+918899887788"; - const workinghours = "8"; - const doctorQualification = "MBBS"; - const doctorYoE = "10"; - const medicalCouncilRegistration = "1234567890"; - - const facilitySearch = "Dummy Facility 40"; - - before(() => { - loginPage.loginAsDevDoctor(); - cy.saveLocalStorage(); - }); - - beforeEach(() => { - cy.restoreLocalStorage(); - cy.clearLocalStorage(/filters--.+/); - cy.awaitUrl("/user/profile"); - }); - - it("Set Dob, Gender, Email, Phone and Working Hours for a user and verify its reflection in user profile", () => { - userProfilePage.clickEditProfileButton(); - - userProfilePage.typedate_of_birth(date_of_birth); - userProfilePage.selectGender(gender); - userProfilePage.typeEmail(email); - userProfilePage.typePhone(phone); - userProfilePage.typeWhatsApp(phone); - userProfilePage.typeWorkingHours(workinghours); - userProfilePage.typeDoctorQualification(doctorQualification); - userProfilePage.typeDoctorYoE(doctorYoE); - userProfilePage.typeMedicalCouncilRegistration(medicalCouncilRegistration); - - userProfilePage.clickUpdateButton(); - - cy.verifyNotification("Details updated successfully"); - - userProfilePage.assertdate_of_birth("01/01/1999"); - userProfilePage.assertGender(gender); - userProfilePage.assertEmail(email); - userProfilePage.assertPhone(phone); - userProfilePage.assertWhatsApp(phone); - userProfilePage.assertWorkingHours(workinghours); - }); - - it("Adding video connect link for a user and verify its reflection in user profile and doctor connect", () => { - // verify the user doesn't have any video connect link - userProfilePage.assertVideoConnectLink("-"); - // Link a new video connect link and ensure it is under video connect link - userProfilePage.clickEditProfileButton(); - userProfilePage.typeVideoConnectLink("https://www.example.com"); - userProfilePage.clickUpdateButton(); - userProfilePage.assertVideoConnectLink("https://www.example.com"); - // Edit the video connect link and ensure it is updated - userProfilePage.clickEditProfileButton(); - userProfilePage.typeVideoConnectLink("https://www.test.com"); - userProfilePage.clickUpdateButton(); - userProfilePage.assertVideoConnectLink("https://www.test.com"); - // Go to particular facility doctor connect and verify the video connect link is present - manageUserPage.navigateToFacility(); - manageUserPage.typeFacilitySearch(facilitySearch); - manageUserPage.assertFacilityInCard(facilitySearch); - manageUserPage.clickFacilityPatients(); - manageUserPage.clickDoctorConnectButton(); - manageUserPage.assertVideoConnectLink("Dev Doctor", "https://www.test.com"); - }); - - afterEach(() => { - cy.saveLocalStorage(); - }); -}); diff --git a/cypress/pageobject/Asset/AssetCreation.ts b/cypress/pageobject/Asset/AssetCreation.ts index 2484bb5affe..11c2c912114 100644 --- a/cypress/pageobject/Asset/AssetCreation.ts +++ b/cypress/pageobject/Asset/AssetCreation.ts @@ -62,7 +62,9 @@ export class AssetPage { cy.get( "[data-testid=asset-last-serviced-on-input] input[type='text']", ).click(); - cy.get("#date-input").click().type(lastServicedOn); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click(0, 0) + .type(lastServicedOn); cy.get("body").click(0, 0); cy.get("[data-testid=asset-notes-input] textarea").type(notes); } @@ -121,7 +123,12 @@ export class AssetPage { cy.get( "[data-testid=asset-last-serviced-on-input] input[type='text']", ).click(); - cy.get("#date-input").click().clear().type(lastServicedOn); + cy.get( + '[data-test-id="date-input"]:visible [data-test-id="clear-date-input"]', + ).click(); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(lastServicedOn); cy.get("body").click(0, 0); cy.get("[data-testid=asset-notes-input] textarea").clear().type(notes); } @@ -278,7 +285,9 @@ export class AssetPage { enterAssetservicedate(text: string) { cy.get("input[name='last_serviced_on']").click(); - cy.get("#date-input").click().type(text); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(text); cy.get("body").click(0, 0); } diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index 0552a130adc..3001beb4a3b 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -246,7 +246,9 @@ class FacilityPage { fillEntryDate(date) { cy.get("#entry_date").click(); - cy.get("#date-input").click().type(date); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(date); cy.get("body").click(0, 0); } diff --git a/cypress/pageobject/Patient/PatientConsultation.ts b/cypress/pageobject/Patient/PatientConsultation.ts index 470febaa852..86c66d846be 100644 --- a/cypress/pageobject/Patient/PatientConsultation.ts +++ b/cypress/pageobject/Patient/PatientConsultation.ts @@ -61,7 +61,12 @@ export class PatientConsultationPage { typePatientConsultationDate(selector: string, date: string) { cy.get(selector).click(); - cy.get("#date-input").clear().type(date); + cy.get( + '[data-test-id="date-input"]:visible [data-test-id="clear-date-input"]', + ).click(); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(date); cy.get("body").click(0, 0); } diff --git a/cypress/pageobject/Patient/PatientCreation.ts b/cypress/pageobject/Patient/PatientCreation.ts index f0cb415df95..4b101849e70 100644 --- a/cypress/pageobject/Patient/PatientCreation.ts +++ b/cypress/pageobject/Patient/PatientCreation.ts @@ -54,7 +54,9 @@ export class PatientPage { cy.clickAndSelectOption("#patientAge", "DOB"); cy.get("#date_of_birth").scrollIntoView(); cy.get("#date_of_birth").should("be.visible").click(); - cy.get("#date-input").click().type(dateOfBirth); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(dateOfBirth); cy.get("body").click(0, 0); } @@ -82,13 +84,17 @@ export class PatientPage { typeLastMenstruationStartDate(date: string) { cy.get("#last_menstruation_start_date").click(); - cy.get("#date-input").click().type(date); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(date); cy.get("body").click(0, 0); } typeDateOfDelivery(date: string) { cy.get("#date_of_delivery").click(); - cy.get("#date-input").click().type(date); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(date); cy.get("body").click(0, 0); } diff --git a/cypress/pageobject/Patient/PatientPredefined.ts b/cypress/pageobject/Patient/PatientPredefined.ts index f865281c202..f0a005ec97b 100644 --- a/cypress/pageobject/Patient/PatientPredefined.ts +++ b/cypress/pageobject/Patient/PatientPredefined.ts @@ -17,7 +17,7 @@ class PatientPredefined { const emergency_phone_number = generateEmergencyPhoneNumber(); patientPage.typePatientPhoneNumber(phone_number); patientPage.typePatientEmergencyNumber(emergency_phone_number); - patientPage.typePatientDateOfBirth("01/01/2001"); + patientPage.typePatientDateOfBirth("01012001"); patientPage.typePatientName("Patient With Predefined Data"); patientPage.selectPatientGender("Male"); patientPage.typePatientAddress("Test Patient Address"); diff --git a/cypress/pageobject/Patient/PatientTreatmentPlan.ts b/cypress/pageobject/Patient/PatientTreatmentPlan.ts index a78cc3d4a0c..d78f82ba229 100644 --- a/cypress/pageobject/Patient/PatientTreatmentPlan.ts +++ b/cypress/pageobject/Patient/PatientTreatmentPlan.ts @@ -34,7 +34,12 @@ class PatientTreatmentPlan { typeProcedureTime(time: string) { cy.get("#procedure-time").click(); - cy.get("#date-input").clear().type(time); + cy.get( + '[data-test-id="date-input"]:visible [data-test-id="clear-date-input"]', + ).click(); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(time); cy.get("body").click(0, 0); } diff --git a/cypress/pageobject/Users/UserCreation.ts b/cypress/pageobject/Users/UserCreation.ts index 7503ea3fb07..5442ec9d943 100644 --- a/cypress/pageobject/Users/UserCreation.ts +++ b/cypress/pageobject/Users/UserCreation.ts @@ -19,7 +19,12 @@ export class UserCreationPage { } typeIntoElementByIdPostClearDob(elementId: string, value: string) { cy.get("#" + elementId).click(); - cy.get("#date-input").clear().type(value); + cy.get( + '[data-test-id="date-input"]:visible [data-test-id="clear-date-input"]', + ).click(); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]') + .click() + .type(value); } clearIntoElementById(elementId: string) { cy.get("#" + elementId) @@ -54,13 +59,9 @@ export class UserCreationPage { this.selectOptionContainingText(name); } - setInputDate( - dateElementId: string, - inputElementId: string, - dateValue: string, - ) { + setInputDate(dateElementId: string, dateValue: string) { this.clickElementById(dateElementId); - this.typeIntoElementById(inputElementId, dateValue); + cy.get(`[data-test-id="date-input"]:visible`).click().type(dateValue); } selectDropdownOption(dropdownId: string, optionText: string) { diff --git a/cypress/pageobject/Users/UserProfilePage.ts b/cypress/pageobject/Users/UserProfilePage.ts index 20fd1911c49..4b9196ed5f5 100644 --- a/cypress/pageobject/Users/UserProfilePage.ts +++ b/cypress/pageobject/Users/UserProfilePage.ts @@ -18,7 +18,12 @@ export default class UserProfilePage { typedate_of_birth(date_of_birth: string) { //check cy.get("#date_of_birth").click(); - cy.get("#date-input").clear().type(date_of_birth); + cy.get( + '[data-test-id="date-input"]:visible [data-test-id="clear-date-input"]', + ).click(); + cy.get('[data-test-id="date-input"]:visible [data-time-input="0"]').type( + date_of_birth, + ); } selectGender(gender: string) { diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index d6ec9e067f9..9cd25bf9b12 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -173,10 +173,15 @@ Cypress.Commands.add("selectRadioOption", (name: string, value: string) => { cy.get(`input[type='radio'][name='${name}'][value=${value}]`).click(); }); -Cypress.Commands.add("clickAndTypeDate", (selector: string, date: string) => { +Cypress.Commands.add("clickAndTypeDate", (selector, date) => { cy.get(selector).scrollIntoView(); cy.get(selector).click(); - cy.get("#date-input").click().type(date); + cy.get( + `[data-test-id="date-input"]:visible [data-test-id="clear-date-input"]`, + ).click(); + cy.get(`[data-test-id="date-input"]:visible [data-time-input="0"]`) + .click() + .type(date); cy.get("body").click(0, 0); }); diff --git a/src/Components/Common/DateInputV2.tsx b/src/Components/Common/DateInputV2.tsx index cc678768ebe..92ad574b4c9 100644 --- a/src/Components/Common/DateInputV2.tsx +++ b/src/Components/Common/DateInputV2.tsx @@ -28,7 +28,7 @@ interface Props { min?: Date; max?: Date; outOfLimitsErrorMessage?: string; - onChange: (date: Date) => void; + onChange: (date: Date | undefined) => void; position?: DatePickerPosition; disabled?: boolean; placeholder?: string; diff --git a/src/Components/Common/DateTextInput.tsx b/src/Components/Common/DateTextInput.tsx index 882eb410834..94384b9da36 100644 --- a/src/Components/Common/DateTextInput.tsx +++ b/src/Components/Common/DateTextInput.tsx @@ -1,3 +1,4 @@ +import CareIcon from "@/CAREUI/icons/CareIcon"; import { classNames } from "@/Utils/utils"; import dayjs from "dayjs"; import { Fragment, KeyboardEvent, useEffect, useState } from "react"; @@ -16,7 +17,7 @@ import { Fragment, KeyboardEvent, useEffect, useState } from "react"; export default function DateTextInput(props: { allowTime: boolean; value?: Date; - onChange: (date: Date) => unknown; + onChange: (date: Date | undefined) => unknown; error?: string; }) { const { value, onChange, allowTime, error } = props; @@ -56,7 +57,9 @@ export default function DateTextInput(props: { const index = Object.keys(editingText).findIndex((et) => et === key); const value = Math.min(maxMap[index], parseInt(rawValue)); const finalValue = - rawValue !== "" ? ("000" + value).slice(key === "year" ? -4 : -2) : ""; + rawValue.trim() !== "" + ? ("000" + value).slice(key === "year" ? -4 : -2) + : ""; return finalValue; }; @@ -115,12 +118,16 @@ export default function DateTextInput(props: {
- e.target === e.currentTarget && goToInput(allowTime ? 4 : 2) + e.target === e.currentTarget && + (value ? goToInput(allowTime ? 4 : 2) : goToInput(0)) } + data-test-id="date-input" > {Object.entries(editingText) .slice(0, allowTime ? 5 : 3) @@ -141,12 +148,6 @@ export default function DateTextInput(props: { data-time-input={i} onChange={(e) => { const value = e.target.value; - setEditingText({ - ...editingText, - [key]: value - .replace(/\D/g, "") - .slice(0, key === "year" ? 4 : 2), - }); if ( (value.endsWith("/") || value.endsWith(" ") || @@ -155,6 +156,13 @@ export default function DateTextInput(props: { i < 4 ) { goToInput(i + 1); + } else { + setEditingText({ + ...editingText, + [key]: value + .replace(/\D/g, "") + .slice(0, key === "year" ? 4 : 2), + }); } }} onBlur={(e) => handleBlur(e.target.value, key)} @@ -168,6 +176,21 @@ export default function DateTextInput(props: { ))} + +
{error && {error}}
diff --git a/src/Components/Facility/CoverImageEditModal.tsx b/src/Components/Facility/CoverImageEditModal.tsx index d65a1d0ebfd..f3b2b3ab761 100644 --- a/src/Components/Facility/CoverImageEditModal.tsx +++ b/src/Components/Facility/CoverImageEditModal.tsx @@ -1,11 +1,11 @@ -import { +import React, { + useState, ChangeEventHandler, useCallback, useEffect, useRef, - useState, } from "react"; -import { Success } from "../../Utils/Notifications"; +import { Success, Warn } from "../../Utils/Notifications"; import useDragAndDrop from "../../Utils/useDragAndDrop"; import { sleep } from "../../Utils/utils"; import ButtonV2, { Cancel, Submit } from "../Common/components/ButtonV2"; @@ -67,9 +67,11 @@ const CoverImageEditModal = ({ const LaptopScreenBreakpoint = 640; const isLaptopScreen = width >= LaptopScreenBreakpoint; const { t } = useTranslation(); + const [isDragging, setIsDragging] = useState(false); + const handleSwitchCamera = useCallback(() => { - setConstraint((prev) => - prev.facingMode === "user" + setConstraint( + constraint.facingMode === "user" ? VideoConstraints.environment : VideoConstraints.user, ); @@ -85,6 +87,7 @@ const CoverImageEditModal = ({ setSelectedFile(myFile); }); }; + const closeModal = () => { setPreview(undefined); setSelectedFile(undefined); @@ -162,11 +165,25 @@ const CoverImageEditModal = ({ const onDrop = (e: React.DragEvent) => { e.preventDefault(); dragProps.setDragOver(false); - const dropedFile = e?.dataTransfer?.files[0]; - if (dropedFile.type.split("/")[0] !== "image") + setIsDragging(false); + const droppedFile = e?.dataTransfer?.files[0]; + if (droppedFile.type.split("/")[0] !== "image") return dragProps.setFileDropError("Please drop an image file to upload!"); - setSelectedFile(dropedFile); + setSelectedFile(droppedFile); + }; + + const onDragOver = (e: React.DragEvent) => { + e.preventDefault(); + dragProps.onDragOver(e); + setIsDragging(true); + }; + + const onDragLeave = (e: React.DragEvent) => { + e.preventDefault(); + dragProps.onDragLeave(); + setIsDragging(false); }; + const commonHint = ( <> {t("max_size_for_image_uploaded_should_be")} 1mb. @@ -202,16 +219,16 @@ const CoverImageEditModal = ({ ) : (

{ + setConstraint(() => VideoConstraints.user); setIsCameraOpen(true); }} > @@ -322,6 +346,10 @@ const CoverImageEditModal = ({ width={1280} ref={webRef} videoConstraints={constraint} + onUserMediaError={(_e) => { + setIsCameraOpen(false); + Warn({ msg: t("camera_permission_denied") }); + }} /> ) : ( diff --git a/src/Components/Facility/LocationManagement.tsx b/src/Components/Facility/LocationManagement.tsx index 8df40d9c5f2..1aaf57b7233 100644 --- a/src/Components/Facility/LocationManagement.tsx +++ b/src/Components/Facility/LocationManagement.tsx @@ -13,6 +13,7 @@ import ConfirmDialog from "../Common/ConfirmDialog"; import DialogModal from "../Common/Dialog"; import Uptime from "../Common/Uptime"; import useAuthUser from "../../Common/hooks/useAuthUser"; +import useQuery from "../../Utils/request/useQuery"; import Loading from "@/Components/Common/Loading"; interface Props { @@ -223,97 +224,120 @@ const Location = ({ disabled, setShowDeletePopup, facilityId, -}: LocationProps) => ( -

-
-
-
-

- {name} -

-
-

- {location_type} +}: LocationProps) => { + const { loading, data } = useQuery(routes.listFacilityBeds, { + query: { + facility: facilityId, + location: id, + }, + }); + + const totalBeds = data?.count ?? 0; + + if (loading) { + return ; + } + + return ( +

+
+
+
+

+ {name}

+
+

+ {location_type} +

+
-
-

- {description || "-"} -

-

- Middleware Address: -

-

- {middleware_address || "-"} -

- - Middleware Uptime -

- } - centerInfoPanel - /> -
- - - - Manage Beds - -
-
- - - Edit - -
-
- - setShowDeletePopup({ open: true, name: name ?? "", id: id ?? "" }) - } + {description || "-"} +

+

+ Middleware Address: +

+

- - Delete - + {middleware_address || "-"} +

+ + Middleware Uptime +

+ } + centerInfoPanel + />
-
-
- - + + Manage Beds + + + {totalBeds} + + +
+
+ + + Edit + +
+
+ + setShowDeletePopup({ open: true, name: name ?? "", id: id ?? "" }) + } + > + + Delete + +
+
+ +
+ + +
-
-); + ); +}; diff --git a/src/Components/Form/Form.tsx b/src/Components/Form/Form.tsx index 31afc594447..4bf4bd22d01 100644 --- a/src/Components/Form/Form.tsx +++ b/src/Components/Form/Form.tsx @@ -13,7 +13,6 @@ type Props = { className?: string; defaults: T; asyncGetDefaults?: (() => Promise) | false; - onlyChild?: boolean; validate?: (form: T) => FormErrors; onSubmit: (form: T) => Promise | void>; onCancel?: () => void; @@ -23,6 +22,7 @@ type Props = { cancelLabel?: string; onDraftRestore?: (newState: FormState) => void; children: (props: FormContextValue) => React.ReactNode; + hideRestoreDraft?: boolean; }; const Form = ({ @@ -87,47 +87,43 @@ const Form = ({ props.onDraftRestore?.(newState); }} formData={state.form} - /> - ) => { - return { - name, - id: name, - onChange: ({ name, value }: FieldChangeEvent) => - dispatch({ - type: "set_field", - name, - value, - error: validate?.(value), - }), - value: state.form[name], - error: state.errors[name], - disabled, - }; - }} + hidden={props.hideRestoreDraft} > - {props.onlyChild ? ( - {props.children} - ) : ( - <> -
- {props.children} -
-
- - -
- - )} -
+ ) => { + return { + name, + id: name, + onChange: ({ name, value }: FieldChangeEvent) => + dispatch({ + type: "set_field", + name, + value, + error: validate?.(value), + }), + value: state.form[name], + error: state.errors[name], + disabled, + }; + }} + > +
+ {props.children} +
+
+ + +
+
+ ); }; diff --git a/src/Components/Form/FormFields/DateFormField.tsx b/src/Components/Form/FormFields/DateFormField.tsx index 6d466d25194..5d0b6be0892 100644 --- a/src/Components/Form/FormFields/DateFormField.tsx +++ b/src/Components/Form/FormFields/DateFormField.tsx @@ -44,7 +44,7 @@ const DateFormField = (props: Props) => { ? new Date(field.value) : field.value } - onChange={field.handleChange} + onChange={field.handleChange as (d?: Date) => void} disabled={field.disabled} max={props.max ?? (props.disableFuture ? new Date() : undefined)} min={props.min ?? (props.disablePast ? yesterday() : undefined)} diff --git a/src/Components/Patient/PatientHome.tsx b/src/Components/Patient/PatientHome.tsx index 2ee78b6bce1..f6fe4f28a72 100644 --- a/src/Components/Patient/PatientHome.tsx +++ b/src/Components/Patient/PatientHome.tsx @@ -318,11 +318,11 @@ export const PatientHome = (props: any) => { />
- {t("consultation_not_found")} + {t("consultation_not_filed")} - {t("consultation_not_found_description")} + {t("consultation_not_filed_description")}
diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx index 8e9a284f7e5..58a882d184d 100644 --- a/src/Components/Patient/PatientRegister.tsx +++ b/src/Components/Patient/PatientRegister.tsx @@ -70,6 +70,7 @@ import { Button } from "@/Components/ui/button"; import Loading from "@/Components/Common/Loading"; import PageTitle from "@/Components/Common/PageTitle"; +import { RestoreDraftButton } from "@/Utils/AutoSave.js"; type PatientForm = PatientModel & PatientMeta & { age?: number; is_postpartum?: boolean }; @@ -916,974 +917,937 @@ export const PatientRegister = (props: PatientRegisterProps) => { } return ( -
- {statusDialog.show && ( - { - handleDialogClose("close"); - setResetNum(true); - }} - /> - )} - {statusDialog.transfer && ( - { - setResetNum(true); - handleDialogClose("close"); - }} - title="Patient Transfer Form" - className="max-w-md md:min-w-[600px]" - > - handleDialogClose("close")} - handleCancel={() => { - setResetNum(true); - handleDialogClose("close"); - }} - facilityId={facilityId} - /> - - )} - { - id - ? navigate(`/facility/${facilityId}/patient/${id}`) - : navigate(`/facility/${facilityId}`); - }} - componentRight={ - !state.form.abha_number && ( - - ) + + defaults={id ? state.form : initForm} + validate={validateForm} + onSubmit={handleSubmit} + submitLabel={buttonText} + onCancel={() => navigate("/facility")} + className="bg-transparent px-1 py-2 md:px-2" + onDraftRestore={(newState) => { + dispatch({ type: "set_state", state: newState }); + Promise.all([ + fetchDistricts(newState.form.state ?? 0), + fetchLocalBody(newState.form.district?.toString() ?? ""), + fetchWards(newState.form.local_body?.toString() ?? ""), + duplicateCheck(newState.form.phone_number ?? ""), + ]); + }} + noPadding + hideRestoreDraft + > + {(field) => { + if (!formField) setFormField(field); + if (resetNum) { + field("phone_number").onChange({ + name: "phone_number", + value: "+91", + }); + setResetNum(false); } - crumbsReplacements={{ - [facilityId]: { name: facilityObject?.name }, - [id ?? "????"]: { name: patientName }, - }} - /> -
-
-
- {" "} - Please enter the correct date of birth for the patient -
-

- Each patient in the system is uniquely identifiable by the number - and date of birth. Adding incorrect date of birth can result in - duplication of patient records. -

-
- <> - {showAlertMessage.show && ( - goBack()} - onClose={() => goBack()} - variant="primary" - action="Ok" - show - /> - )} - <> - - defaults={id ? state.form : initForm} - validate={validateForm} - onSubmit={handleSubmit} - submitLabel={buttonText} - onCancel={() => navigate("/facility")} - className="bg-transparent px-1 py-2 md:px-2" - onDraftRestore={(newState) => { - dispatch({ type: "set_state", state: newState }); - Promise.all([ - fetchDistricts(newState.form.state ?? 0), - fetchLocalBody(newState.form.district?.toString() ?? ""), - fetchWards(newState.form.local_body?.toString() ?? ""), - duplicateCheck(newState.form.phone_number ?? ""), - ]); + return ( +
+ {statusDialog.show && ( + { + handleDialogClose("close"); + setResetNum(true); + }} + /> + )} + {statusDialog.transfer && ( + { + setResetNum(true); + handleDialogClose("close"); + }} + title="Patient Transfer Form" + className="max-w-md md:min-w-[600px]" + > + handleDialogClose("close")} + handleCancel={() => { + setResetNum(true); + handleDialogClose("close"); + }} + facilityId={facilityId} + /> + + )} + { + id + ? navigate(`/facility/${facilityId}/patient/${id}`) + : navigate(`/facility/${facilityId}`); }} - noPadding - > - {(field) => { - if (!formField) setFormField(field); - if (resetNum) { - field("phone_number").onChange({ - name: "phone_number", - value: "+91", - }); - setResetNum(false); - } - return ( - <> - {careConfig.abdm.enabled && ( -
- {showLinkAbhaNumberModal && ( - setShowLinkAbhaNumberModal(false)} - onSuccess={(data: any) => { - if (id) { - navigate( - `/facility/${facilityId}/patient/${id}`, - ); - return; - } + componentRight={} + crumbsReplacements={{ + [facilityId]: { name: facilityObject?.name }, + [id ?? "????"]: { name: patientName }, + }} + /> +
+
+
+ {" "} + Please enter the correct date of birth for the patient +
+

+ Each patient in the system is uniquely identifiable by the + number and date of birth. Adding incorrect date of birth can + result in duplication of patient records. +

+
+ {!state.form.abha_number && ( +
+ +
+ )} + {showAlertMessage.show && ( + goBack()} + onClose={() => goBack()} + variant="primary" + action="Ok" + show + /> + )} + {careConfig.abdm.enabled && ( +
+ {showLinkAbhaNumberModal && ( + setShowLinkAbhaNumberModal(false)} + onSuccess={(data: any) => { + if (id) { + navigate(`/facility/${facilityId}/patient/${id}`); + return; + } - handleAbhaLinking(data, field); - }} - /> - )} - {state.form.abha_number && ( -
-
- null} - disabled={true} - error="" - /> -
-
- {state.form.health_id ? ( - null} - disabled={true} - error="" - /> - ) : ( -
- No Abha Address Associated with this ABHA - Number -
- )} -
-
- )} + handleAbhaLinking(data, field); + }} + /> + )} + {state.form.abha_number && ( +
+
+ null} + disabled={true} + error="" + />
- )} -
-

- Personal Details -

-
-
- { - if (!id) duplicateCheck(event.value); - field("phone_number").onChange(event); - if (isEmergencyNumberEnabled) { - field("emergency_phone_number").onChange({ - name: field("emergency_phone_number").name, - value: event.value, - }); - } - }} - types={["mobile", "landline"]} - /> - { - setIsEmergencyNumberEnabled(value); - value - ? field("emergency_phone_number").onChange({ - name: field("emergency_phone_number").name, - value: field("phone_number").value, - }) - : field("emergency_phone_number").onChange({ - name: field("emergency_phone_number").name, - value: initForm.emergency_phone_number, - }); - }} - /> -
-
- -
-
+
+ {state.form.health_id ? ( null} + disabled={true} + error="" /> -
-
- - {ageInputType === "age" ? "Age" : "Date of Birth"} - -
- + No Abha Address Associated with this ABHA Number +
+ )} +
+
+ )} +
+ )} +
+

+ Personal Details +

+
+
+ { + if (!id) duplicateCheck(event.value); + field("phone_number").onChange(event); + if (isEmergencyNumberEnabled) { + field("emergency_phone_number").onChange({ + name: field("emergency_phone_number").name, + value: event.value, + }); + } + }} + types={["mobile", "landline"]} + /> + { + setIsEmergencyNumberEnabled(value); + value + ? field("emergency_phone_number").onChange({ + name: field("emergency_phone_number").name, + value: field("phone_number").value, + }) + : field("emergency_phone_number").onChange({ + name: field("emergency_phone_number").name, + value: initForm.emergency_phone_number, + }); + }} + /> +
+
+ +
+
+ +
+
+ + {ageInputType === "age" ? "Age" : "Date of Birth"} + +
+ o.text} + optionValue={(o) => + o.value === "date_of_birth" ? "date_of_birth" : "age" + } + value={ageInputType} + onChange={(v) => { + if (v === "age" && ageInputType === "date_of_birth") { + setAgeInputType("alert_for_age"); + return; + } + setAgeInputType(v); + }} + /> +
+ {ageInputType !== "age" ? ( +
+ o.text} - optionValue={(o) => - o.value === "date_of_birth" - ? "date_of_birth" - : "age" - } - value={ageInputType} - onChange={(v) => { - if ( - v === "age" && - ageInputType === "date_of_birth" - ) { - setAgeInputType("alert_for_age"); - return; - } - setAgeInputType(v); - }} + position="LEFT" + disableFuture /> -
- {ageInputType !== "age" ? ( -
- -
- ) : ( -
- - {field("age").value !== "" && ( - <> - - Year of Birth: - - - YOB: - - - {new Date().getFullYear() - - field("age").value} - - - )} -

- } - placeholder="Enter the age" - type="number" - min={0} - /> -
- )} -
- -
- -
- While entering a patient's age is an option, - please note that only the year of birth will - be captured from this information. -
- - Recommended only when the patient's date of - birth is unknown - -
+ ) : ( +
+ + {field("age").value !== "" && ( + <> + + Year of Birth: + + + YOB: + + + {new Date().getFullYear() - + field("age").value} + + + )} +

} - action="Confirm" - variant="warning" - show={ageInputType == "alert_for_age"} - onClose={() => setAgeInputType("date_of_birth")} - onConfirm={() => setAgeInputType("age")} + placeholder="Enter the age" + type="number" + min={0} />
-
-
+ )} +
+
+ +
+ +
+ While entering a patient's age is an option, + please note that only the year of birth will be + captured from this information. +
+ + Recommended only when the patient's date of birth + is unknown + +
+ } + action="Confirm" + variant="warning" + show={ageInputType == "alert_for_age"} + onClose={() => setAgeInputType("date_of_birth")} + onConfirm={() => setAgeInputType("age")} + /> +
+
+
+ { + field("gender").onChange(e); + if (e.value !== "2") { + field("is_antenatal").onChange({ + name: "is_antenatal", + value: "false", + }); + + field("is_postpartum").onChange({ + name: "is_postpartum", + value: "false", + }); + } + }} + optionLabel={(o: any) => o.text} + optionValue={(o: any) => o.id} + /> +
+ + { +
+ option.label} + optionValue={(option) => option.value} + /> +
+ } +
+ + { +
+ +
+ } +
+ + option.label} + optionValue={(option) => option.value} + /> + + + + +
+ +
+
+ + +
+ +
+ { + field("pincode").onChange(e); + handlePincodeChange(e, field("pincode").onChange); + }} + /> + {showAutoFilledPincode && ( +
+ + + State and District auto-filled from Pincode + +
+ )} +
+
+ +
+
+ o} + optionValue={(o) => o} + /> +
+ {field("nationality").value === "India" ? ( + <> +
+ {isStateLoading ? ( + + ) : ( { - field("gender").onChange(e); - if (e.value !== "2") { - field("is_antenatal").onChange({ - name: "is_antenatal", - value: "false", - }); - - field("is_postpartum").onChange({ - name: "is_postpartum", - value: "false", - }); - } - }} - optionLabel={(o: any) => o.text} + placeholder="Choose State" + options={stateData ? stateData.results : []} + optionLabel={(o: any) => o.name} optionValue={(o: any) => o.id} + onChange={(e: any) => { + field("state").onChange(e); + field("district").onChange({ + name: "district", + value: undefined, + }); + field("local_body").onChange({ + name: "local_body", + value: undefined, + }); + field("ward").onChange({ + name: "ward", + value: undefined, + }); + fetchDistricts(e.value); + fetchLocalBody("0"); + fetchWards("0"); + }} /> -
- - { -
- option.label} - optionValue={(option) => option.value} - /> -
- } -
- - { -
- -
- } -
- - option.label} - optionValue={(option) => option.value} - /> - - - - -
- -
-
- + +
+ {isDistrictLoading ? ( +
+ +
+ ) : ( + o.name} + optionValue={(o: any) => o.id} + onChange={(e: any) => { + field("district").onChange(e); + field("local_body").onChange({ + name: "local_body", + value: undefined, + }); + field("ward").onChange({ + name: "ward", + value: undefined, + }); + fetchLocalBody(String(e.value)); + fetchWards("0"); + }} /> - -
+ )} +
-
- + {isLocalbodyLoading ? ( +
+ +
+ ) : ( + o.name} + optionValue={(o) => o.id} onChange={(e) => { - field("pincode").onChange(e); - handlePincodeChange(e, field("pincode").onChange); + field("local_body").onChange(e); + field("ward").onChange({ + name: "ward", + value: undefined, + }); + fetchWards(String(e.value)); }} /> - {showAutoFilledPincode && ( -
- - - State and District auto-filled from Pincode - -
- )} -
-
- -
-
+ )} +
+
+ {isWardLoading ? ( +
+ +
+ ) : ( o} - optionValue={(o) => o} + {...field("ward")} + label="Ward" + options={ward.sort(compareBy("number")).map((e) => { + return { + id: e.id, + name: e.number + ": " + e.name, + }; + })} + placeholder={ + field("local_body").value + ? "Choose Ward" + : "Select Localbody First" + } + disabled={!field("local_body").value} + optionLabel={(o: any) => o.name} + optionValue={(o: any) => o.id} + onChange={(e: any) => { + field("ward").onChange(e); + }} /> -
- {field("nationality").value === "India" ? ( - <> -
- {isStateLoading ? ( - - ) : ( - o.name} - optionValue={(o: any) => o.id} - onChange={(e: any) => { - field("state").onChange(e); - field("district").onChange({ - name: "district", - value: undefined, - }); - field("local_body").onChange({ - name: "local_body", - value: undefined, - }); - field("ward").onChange({ - name: "ward", - value: undefined, - }); - fetchDistricts(e.value); - fetchLocalBody("0"); - fetchWards("0"); - }} - /> - )} -
- -
- {isDistrictLoading ? ( -
- -
- ) : ( - o.name} - optionValue={(o: any) => o.id} - onChange={(e: any) => { - field("district").onChange(e); - field("local_body").onChange({ - name: "local_body", - value: undefined, - }); - field("ward").onChange({ - name: "ward", - value: undefined, - }); - fetchLocalBody(String(e.value)); - fetchWards("0"); - }} - /> - )} -
- -
- {isLocalbodyLoading ? ( -
- -
- ) : ( - o.name} - optionValue={(o) => o.id} - onChange={(e) => { - field("local_body").onChange(e); - field("ward").onChange({ - name: "ward", - value: undefined, - }); - fetchWards(String(e.value)); - }} - /> - )} -
-
- {isWardLoading ? ( -
- -
- ) : ( - { - return { - id: e.id, - name: e.number + ": " + e.name, - }; - })} - placeholder={ - field("local_body").value - ? "Choose Ward" - : "Select Localbody First" - } - disabled={!field("local_body").value} - optionLabel={(o: any) => o.name} - optionValue={(o: any) => o.id} - onChange={(e: any) => { - field("ward").onChange(e); - }} - /> - )} -
- - ) : ( -
- -
)}
+ + ) : ( +
+
- {field("nationality").value === "India" && ( -
- + )} +
+
+ {field("nationality").value === "India" && ( +
+ + } + title={ +

+ Social Profile +

+ } + expanded + > +
+
+ o.text} + optionValue={(o) => o.id} + /> + t(`ration_card__${o}`)} + optionValue={(o) => o} + /> + t(`SOCIOECONOMIC_STATUS__${o}`)} + optionValue={(o) => o} + value={field("meta_info").value?.socioeconomic_status} + onChange={({ name, value }) => + field("meta_info").onChange({ + name: "meta_info", + value: { + ...(field("meta_info").value ?? {}), + [name]: value, + }, + }) } - title={ -

- Social Profile -

+ /> + + t(`DOMESTIC_HEALTHCARE_SUPPORT__${o}`) } - expanded - > -
-
- o.text} - optionValue={(o) => o.id} - /> - t(`ration_card__${o}`)} - optionValue={(o) => o} - /> - - t(`SOCIOECONOMIC_STATUS__${o}`) - } - optionValue={(o) => o} - value={ - field("meta_info").value?.socioeconomic_status - } - onChange={({ name, value }) => - field("meta_info").onChange({ - name: "meta_info", - value: { - ...(field("meta_info").value ?? {}), - [name]: value, - }, - }) - } - /> - - t(`DOMESTIC_HEALTHCARE_SUPPORT__${o}`) - } - optionValue={(o) => o} - value={ - field("meta_info").value - ?.domestic_healthcare_support - } - onChange={({ name, value }) => - field("meta_info").onChange({ - name: "meta_info", - value: { - ...(field("meta_info").value ?? {}), - [name]: value, - }, - }) - } - /> -
-
- + optionValue={(o) => o} + value={ + field("meta_info").value + ?.domestic_healthcare_support + } + onChange={({ name, value }) => + field("meta_info").onChange({ + name: "meta_info", + value: { + ...(field("meta_info").value ?? {}), + [name]: value, + }, + }) + } + />
- )} -
- - } - title={ -

- COVID Details -

- } +
+ +
+ )} +
+ + } + title={ +

+ COVID Details +

+ } + > +
+
+
+ option.label} + optionValue={(option) => option.value} + /> +
+
+
+ -
-
-
- option.label} - optionValue={(option) => option.value} + { +
+
+
-
-
- - { -
-
- -
-
- option.label} - optionValue={(option) => option.value} - /> -
-
- o} - optionValue={(o) => o} - /> -
-
- -
-
- } -
-
-
-
+
option.label} optionValue={(option) => option.value} /> - -
- -
-
-
+
+ o} + optionValue={(o) => o} + /> +
+
-
- -
-
-

- Medical History -

-
-
- -
- -
- -
-
- - Any medical history? (Comorbidities) - -
- {MEDICAL_HISTORY_CHOICES.map((i) => { - return renderMedicalHistory( - i.id as number, - i.text, - field, - ); - })} -
- -
- -
- -
- -
- o} - optionValue={(o: any) => o} - /> -
-
+ } +
-
-
-

- Insurance Details -

- - setInsuranceDetails([ - ...insuranceDetails, - { - id: "", - subscriber_id: "", - policy_id: "", - insurer_id: "", - insurer_name: "", - }, - ]) +
+
+ option.label} + optionValue={(option) => option.value} + /> + - - Add Insurance Details - +
+ +
+
+
+
+
- setInsuranceDetails(value)} - error={insuranceDetailsError} - gridView - />
- - ); - }} - - - -
-
+
+ +
+
+

+ Medical History +

+
+
+ +
+ +
+ +
+
+ + Any medical history? (Comorbidities) + +
+ {MEDICAL_HISTORY_CHOICES.map((i) => { + return renderMedicalHistory( + i.id as number, + i.text, + field, + ); + })} +
+ +
+ +
+ +
+ +
+ o} + optionValue={(o: any) => o} + /> +
+
+
+
+
+

+ Insurance Details +

+ + setInsuranceDetails([ + ...insuranceDetails, + { + id: "", + subscriber_id: "", + policy_id: "", + insurer_id: "", + insurer_name: "", + }, + ]) + } + data-testid="add-insurance-button" + > + + Add Insurance Details + +
+ setInsuranceDetails(value)} + error={insuranceDetailsError} + gridView + /> +
+
+
+ ); + }} + ); }; diff --git a/src/Components/Users/UserAdd.tsx b/src/Components/Users/UserAdd.tsx index 855e2cb8f9a..6a87e64425c 100644 --- a/src/Components/Users/UserAdd.tsx +++ b/src/Components/Users/UserAdd.tsx @@ -294,6 +294,7 @@ export const UserAdd = (props: UserProps) => { const handleDateChange = (e: FieldChangeEvent) => { if (dayjs(e.value).isValid()) { + const errors = { ...state.errors, [e.name]: "" }; dispatch({ type: "set_form", form: { @@ -301,10 +302,12 @@ export const UserAdd = (props: UserProps) => { [e.name]: dayjs(e.value).format("YYYY-MM-DD"), }, }); + dispatch({ type: "set_errors", errors }); } }; const handleFieldChange = (event: FieldChangeEvent) => { + const errors = { ...state.errors, [event.name]: "" }; dispatch({ type: "set_form", form: { @@ -312,6 +315,7 @@ export const UserAdd = (props: UserProps) => { [event.name]: event.value, }, }); + dispatch({ type: "set_errors", errors }); }; useAbortableEffect(() => { diff --git a/src/Locale/en.json b/src/Locale/en.json index 94b9168e564..2b47a90bd46 100644 --- a/src/Locale/en.json +++ b/src/Locale/en.json @@ -198,6 +198,7 @@ "retake": "Retake", "submit": "Submit", "camera": "Camera", + "camera_permission_denied": "Camera Permission denied", "submitting": "Submitting", "view_details": "View Details", "type_to_search": "Type to search", @@ -1019,5 +1020,7 @@ "is_declared_positive": "Whether declared positive", "date_declared_positive": "Date of declaring positive", "date_of_result": "Covid confirmation date", - "is_vaccinated": "Whether vaccinated" + "is_vaccinated": "Whether vaccinated", + "consultation_not_filed": "You have not filed any consultation for this patient yet.", + "consultation_not_filed_description": "Please file a consultation for this patient to continue." } diff --git a/src/Locale/hi.json b/src/Locale/hi.json index 3e967c35cb4..4844a2d787d 100644 --- a/src/Locale/hi.json +++ b/src/Locale/hi.json @@ -197,6 +197,7 @@ "retake": "फिर से लेना", "submit": "जमा करना", "camera": "कैमरा", + "camera_permission_denied": "कैमरा अनुमति नहीं दी गई", "submitting": "भेजने से", "view_details": "विवरण देखें", "type_to_search": "खोजने के लिए टाइप करें", @@ -809,4 +810,4 @@ "search_by_username": "उपयोगकर्ता नाम से खोजें", "last_online": "अंतिम ऑनलाइन", "total_users": "कुल उपयोगकर्ता" -} +} \ No newline at end of file diff --git a/src/Locale/kn.json b/src/Locale/kn.json index ee808b5ebc3..a2738edd9e9 100644 --- a/src/Locale/kn.json +++ b/src/Locale/kn.json @@ -197,6 +197,7 @@ "retake": "ಮರುಪಡೆಯಿರಿ", "submit": "ಸಲ್ಲಿಸಿ", "camera": "ಕ್ಯಾಮೆರಾ", + "camera_permission_denied": "ಕ್ಯಾಮೆರಾ ಅನುಮತಿ ನಿರಾಕರಿಸಲಾಗಿದೆ", "submitting": "ಸಲ್ಲಿಸಲಾಗುತ್ತಿದೆ", "view_details": "ವಿವರಗಳನ್ನು ವೀಕ್ಷಿಸಿ", "type_to_search": "ಹುಡುಕಲು ಟೈಪ್ ಮಾಡಿ", diff --git a/src/Locale/ml.json b/src/Locale/ml.json index 00f649c6952..614a4005ef9 100644 --- a/src/Locale/ml.json +++ b/src/Locale/ml.json @@ -197,6 +197,7 @@ "retake": "വീണ്ടും എടുക്കുക", "submit": "സമർപ്പിക്കുക", "camera": "ക്യാമറ", + "camera_permission_denied": "ക്യാമറ അനുമതി നിഷേധിച്ചു", "submitting": "സമർപ്പിക്കുന്നു", "view_details": "വിശദാംശങ്ങൾ കാണുക", "type_to_search": "തിരയാൻ ടൈപ്പ് ചെയ്യുക", diff --git a/src/Locale/ta.json b/src/Locale/ta.json index ddaebbe2183..cb2eb506bc2 100644 --- a/src/Locale/ta.json +++ b/src/Locale/ta.json @@ -197,6 +197,7 @@ "retake": "மீண்டும் எடுக்கவும்", "submit": "சமர்ப்பிக்கவும்", "camera": "கேமரா", + "camera_permission_denied": "கேமரா அனுமதி நிராகரித்தது", "submitting": "சமர்ப்பிக்கிறது", "view_details": "விவரங்களைக் காண்க", "type_to_search": "தேட தட்டச்சு செய்யவும்", diff --git a/src/Utils/AutoSave.tsx b/src/Utils/AutoSave.tsx index da330a3fc6a..36097581b48 100644 --- a/src/Utils/AutoSave.tsx +++ b/src/Utils/AutoSave.tsx @@ -1,4 +1,12 @@ -import { useReducer, useEffect, useRef, useState, Dispatch } from "react"; +import React, { + useReducer, + useEffect, + useRef, + useState, + Dispatch, + useContext, + ReactNode, +} from "react"; import { Button } from "../Components/ui/button"; import { FormAction, FormReducer, FormState } from "../Components/Form/Utils"; import { relativeTime } from "./utils"; @@ -81,9 +89,20 @@ export function useAutoSaveState(initialState: any) { return [state, setState]; } +type RestoreDraftContextValue = { + handleDraftSelect: (formState: any) => void; + draftStarted: boolean; + drafts: Draft[]; +}; + +const RestoreDraftContext = + React.createContext(null); + export function DraftSection(props: { handleDraftSelect: (formState: any) => void; formData: any; + hidden?: boolean; + children?: ReactNode; }) { const { handleDraftSelect } = props; const [drafts, setDrafts] = useState([]); @@ -123,32 +142,55 @@ export function DraftSection(props: { }, []); return ( - <> - {drafts && drafts.length > 0 && ( + + {!props.hidden && drafts && drafts.length > 0 && (
- +
)} - + {props.children} +
); } + +export const RestoreDraftButton = () => { + const ctx = useContext(RestoreDraftContext); + + if (!ctx) { + throw new Error( + "RestoreDraftButton must be used within a RestoreDraftProvider", + ); + } + + const { handleDraftSelect, draftStarted, drafts } = ctx; + + if (!(drafts && drafts.length > 0)) { + return null; + } + + return ( + + ); +};