diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 4fe94183a2f..40e5259b1c6 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -26,7 +26,7 @@
"cpus": 4
},
"waitFor": "onCreateCommand",
- "postCreateCommand": "npm install",
+ "postCreateCommand": "npm run install-all",
"postAttachCommand": {
"server": "npm run dev"
},
diff --git a/.github/workflows/cypress.yaml b/.github/workflows/cypress.yaml
index 500dbd92be0..0f588568bbc 100644
--- a/.github/workflows/cypress.yaml
+++ b/.github/workflows/cypress.yaml
@@ -70,7 +70,7 @@ jobs:
node-version: "20"
- name: Install dependencies 📦
- run: npm install
+ run: npm run install-all
- name: Build ⚙️
run: npm run build
diff --git a/Dockerfile b/Dockerfile
index 5061a977585..3a96ab3c28a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,6 +13,8 @@ RUN npm install
COPY . .
+RUN npm run setup
+
RUN npm run build
diff --git a/README.md b/README.md
index 7ea8fe1a221..2504bf47fb7 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
diff --git a/cypress/e2e/auth_spec/auth.cy.ts b/cypress/e2e/auth_spec/auth.cy.ts
index a535668ef01..b2bd7b634c0 100644
--- a/cypress/e2e/auth_spec/auth.cy.ts
+++ b/cypress/e2e/auth_spec/auth.cy.ts
@@ -6,6 +6,7 @@ describe("Authorisation/Authentication", () => {
it("Try login as admin with correct password", () => {
cy.loginByApi("devdistrictadmin", "Coronasafe@123");
cy.awaitUrl("/facility");
+ cy.get("#user-profile-name").click();
cy.get("#sign-out-button").contains("Sign Out").click();
cy.url().should("include", "/");
});
diff --git a/cypress/e2e/patient_spec/PatientBedManagement.cy.ts b/cypress/e2e/patient_spec/PatientBedManagement.cy.ts
index d9453806c9f..1964f913a03 100644
--- a/cypress/e2e/patient_spec/PatientBedManagement.cy.ts
+++ b/cypress/e2e/patient_spec/PatientBedManagement.cy.ts
@@ -10,7 +10,7 @@ describe("Patient swtich bed functionality", () => {
const patientConsultationPage = new PatientConsultationPage();
const switchBedOne = "Dummy Bed 4";
const switchBedTwo = "Dummy Bed 1";
- const switchBedThree = "Dummy Bed 3";
+ const switchBedThree = "Dummy Bed 7";
const switchPatientOne = "Dummy Patient 6";
const switchPatientTwo = "Dummy Patient 7";
diff --git a/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts b/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts
index 64d47db2cf1..c1362c328c0 100644
--- a/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts
+++ b/cypress/e2e/patient_spec/PatientDoctorConnect.cy.ts
@@ -8,7 +8,6 @@ describe("Patient Doctor Connect in consultation page", () => {
const doctorconnect = new DoctorConnect();
const patientName = "Dummy Patient 11";
const doctorUser = "Dev Doctor";
- const doctorUserNumber = "+919876543219";
const nurseUser = "Dev Staff";
const teleIcuUser = "Dev Doctor Two";
@@ -37,7 +36,7 @@ describe("Patient Doctor Connect in consultation page", () => {
"#doctor-connect-home-doctor",
doctorUser,
);
- doctorconnect.verifyCopiedContent(doctorUserNumber);
+ doctorconnect.verifyCopiedContent();
// verify the whatsapp and phone number icon presence
doctorconnect.verifyIconVisible("#whatsapp-icon");
doctorconnect.verifyIconVisible("#phone-icon");
diff --git a/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts b/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts
index 94300cdb5c6..9a21eaea51f 100644
--- a/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts
+++ b/cypress/e2e/patient_spec/PatientDoctorNotes.cy.ts
@@ -37,7 +37,7 @@ describe("Patient Discussion notes in the consultation page", () => {
cy.verifyNotification(discussionNotesSuccessMessage);
cy.closeNotification();
// verify the auto-switching of tab to nurse notes if the user is a nurse
- cy.get("#sign-out-button").contains("Sign Out").click();
+ patientDoctorNotes.signout();
loginPage.loginManuallyAsNurse();
loginPage.ensureLoggedIn();
cy.visit("/patients");
diff --git a/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts b/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts
index 7faaeed5a9f..3907784b4b7 100644
--- a/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts
+++ b/cypress/e2e/patient_spec/PatientLogUpdate.cy.ts
@@ -302,9 +302,9 @@ describe("Patient Log Update in Normal, Critical and TeleIcu", () => {
patientRhythm,
]);
patientLogupdate.clickUpdateDetail();
- patientLogupdate.clickClearButtonInElement("#systolic");
+ patientLogupdate.clearIntoElementById("#systolic");
patientLogupdate.typeSystolic(patientModifiedSystolic);
- patientLogupdate.clickClearButtonInElement("#diastolic");
+ patientLogupdate.clearIntoElementById("#diastolic");
patientLogupdate.typeDiastolic(patientModifiedDiastolic);
cy.submitButton("Continue");
cy.verifyNotification("Brief Update updated successfully");
diff --git a/cypress/e2e/users_spec/UsersCreation.cy.ts b/cypress/e2e/users_spec/UsersCreation.cy.ts
index 0f592318888..2c5797fefa7 100644
--- a/cypress/e2e/users_spec/UsersCreation.cy.ts
+++ b/cypress/e2e/users_spec/UsersCreation.cy.ts
@@ -67,6 +67,7 @@ describe("User Creation", () => {
it("Update the existing user profile and verify its reflection", () => {
userCreationPage.clickElementById("user-profile-name");
+ userCreationPage.clickElementById("profile-button");
userCreationPage.verifyElementContainsText(
"username-profile-details",
"devdistrictadmin",
@@ -129,6 +130,7 @@ describe("User Creation", () => {
it("Update the existing user profile Form Mandatory File Error", () => {
userCreationPage.clickElementById("user-profile-name");
+ userCreationPage.clickElementById("profile-button");
userCreationPage.clickElementById("edit-cancel-profile-button");
userCreationPage.clearIntoElementById("firstName");
userCreationPage.clearIntoElementById("lastName");
diff --git a/cypress/pageobject/Facility/FacilityHome.ts b/cypress/pageobject/Facility/FacilityHome.ts
index e021171ff0a..dea7de0e7b6 100644
--- a/cypress/pageobject/Facility/FacilityHome.ts
+++ b/cypress/pageobject/Facility/FacilityHome.ts
@@ -72,7 +72,7 @@ class FacilityHome {
}
verifyOccupancyBadgeVisibility() {
- cy.get("#occupany-badge").should("be.visible");
+ cy.get('[data-test-id="occupancy-badge"]').should("be.visible");
}
verifyAndCloseNotifyModal() {
diff --git a/cypress/pageobject/Login/LoginPage.ts b/cypress/pageobject/Login/LoginPage.ts
index 7ea94d54737..06bd165c9ac 100644
--- a/cypress/pageobject/Login/LoginPage.ts
+++ b/cypress/pageobject/Login/LoginPage.ts
@@ -30,6 +30,8 @@ class LoginPage {
}
ensureLoggedIn(): void {
+ cy.get("#user-profile-name").click();
+ cy.get("#sign-out-button").scrollIntoView();
cy.get("#sign-out-button").contains("Sign Out").should("exist");
}
}
diff --git a/cypress/pageobject/Patient/PatientDoctorConnect.ts b/cypress/pageobject/Patient/PatientDoctorConnect.ts
index b8c33bb4b24..9933c3a1dec 100644
--- a/cypress/pageobject/Patient/PatientDoctorConnect.ts
+++ b/cypress/pageobject/Patient/PatientDoctorConnect.ts
@@ -10,8 +10,8 @@ export class DoctorConnect {
});
}
- verifyCopiedContent(text: string) {
- cy.get("@clipboardStub").should("be.calledWith", text);
+ verifyCopiedContent() {
+ cy.get("@clipboardStub").should("be.calledWithMatch", /^\+91\d{10}$/);
}
verifyIconVisible(selector: string) {
diff --git a/cypress/pageobject/Patient/PatientDoctorNotes.ts b/cypress/pageobject/Patient/PatientDoctorNotes.ts
index 9538b0eed3b..157f35d47d9 100644
--- a/cypress/pageobject/Patient/PatientDoctorNotes.ts
+++ b/cypress/pageobject/Patient/PatientDoctorNotes.ts
@@ -26,4 +26,10 @@ export class PatientDoctorNotes {
.its("response.statusCode")
.should("eq", 201);
}
+
+ signout() {
+ cy.get("#user-profile-name").click();
+ cy.get("#sign-out-button").scrollIntoView();
+ cy.get("#sign-out-button").contains("Sign Out").click();
+ }
}
diff --git a/cypress/pageobject/Patient/PatientLogupdate.ts b/cypress/pageobject/Patient/PatientLogupdate.ts
index 857fe7dd972..d7b49fde05e 100644
--- a/cypress/pageobject/Patient/PatientLogupdate.ts
+++ b/cypress/pageobject/Patient/PatientLogupdate.ts
@@ -43,11 +43,11 @@ class PatientLogupdate {
}
typeSystolic(systolic: string) {
- cy.typeAndSelectOption("#systolic", systolic);
+ cy.get("#systolic").click().type(systolic);
}
typeDiastolic(diastolic: string) {
- cy.typeAndSelectOption("#diastolic", diastolic);
+ cy.get("#diastolic").click().type(diastolic);
}
typePulse(pulse: string) {
@@ -55,7 +55,7 @@ class PatientLogupdate {
}
typeTemperature(temperature: string) {
- cy.typeAndSelectOption("#temperature", temperature);
+ cy.get("#temperature").click().type(temperature);
}
typeRespiratory(respiratory: string) {
@@ -93,8 +93,8 @@ class PatientLogupdate {
cy.wait(3000);
}
- clickClearButtonInElement(elementId: string) {
- cy.get(elementId).find("#clear-button").click();
+ clearIntoElementById(elementId) {
+ cy.get(elementId).click().clear();
}
clickVitals() {
diff --git a/cypress/pageobject/Users/ManageUserPage.ts b/cypress/pageobject/Users/ManageUserPage.ts
index efa0d90142c..470862693a8 100644
--- a/cypress/pageobject/Users/ManageUserPage.ts
+++ b/cypress/pageobject/Users/ManageUserPage.ts
@@ -75,6 +75,7 @@ export class ManageUserPage {
navigateToProfile() {
cy.intercept("GET", "**/api/v1/users/**").as("getUsers");
cy.get("#user-profile-name").click();
+ cy.get("#profile-button").click();
cy.wait("@getUsers").its("response.statusCode").should("eq", 200);
}
diff --git a/package-lock.json b/package-lock.json
index e5bae3c6d02..aa99337d8d6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,9 +19,11 @@
"@hello-pangea/dnd": "^17.0.0",
"@pnotify/core": "^5.2.0",
"@pnotify/mobile": "^5.2.0",
+ "@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-toast": "^1.2.2",
+ "@radix-ui/react-tooltip": "^1.1.3",
"@sentry/browser": "^8.33.0",
"@yudiel/react-qr-scanner": "^2.0.8",
"axios": "^1.7.7",
@@ -3121,6 +3123,28 @@
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
"integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="
},
+ "node_modules/@radix-ui/react-arrow": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
+ "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-collection": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
@@ -3188,6 +3212,20 @@
}
}
},
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
+ "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-dismissable-layer": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz",
@@ -3214,6 +3252,72 @@
}
}
},
+ "node_modules/@radix-ui/react-dropdown-menu": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.2.tgz",
+ "integrity": "sha512-GVZMR+eqK8/Kes0a36Qrv+i20bAPXSn8rCBTHx30w+3ECnR5o3xixAlqcVaYvLeyKUsm0aqyhWfmUcqufM8nYA==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-menu": "2.1.2",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz",
+ "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
+ "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-icons": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz",
@@ -3222,6 +3326,107 @@
"react": "^16.x || ^17.x || ^18.x"
}
},
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-menu": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.2.tgz",
+ "integrity": "sha512-lZ0R4qR2Al6fZ4yCCZzu/ReTFrylHFxIqy7OezIpWF4bL0o9biKo0pFIvkaew3TyZ9Fy5gYVrR5zCGZBVbO1zg==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.1",
+ "@radix-ui/react-focus-guards": "1.1.1",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.2",
+ "@radix-ui/react-presence": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-roving-focus": "1.1.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "aria-hidden": "^1.1.1",
+ "react-remove-scroll": "2.6.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popper": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
+ "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-use-rect": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0",
+ "@radix-ui/rect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-portal": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz",
@@ -3290,6 +3495,50 @@
}
}
},
+ "node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
+ "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-slot": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
@@ -3340,6 +3589,39 @@
}
}
},
+ "node_modules/@radix-ui/react-tooltip": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.3.tgz",
+ "integrity": "sha512-Z4w1FIS0BqVFI2c1jZvb/uDVJijJjJ2ZMuPV81oVgTZ7g3BZxobplnMVvXtFWgtozdvYJ+MFWtwkM5S2HnAong==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-dismissable-layer": "1.1.1",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.2",
+ "@radix-ui/react-presence": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-visually-hidden": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
@@ -3402,6 +3684,40 @@
}
}
},
+ "node_modules/@radix-ui/react-use-rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
+ "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
+ "dependencies": {
+ "@radix-ui/rect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-visually-hidden": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz",
@@ -3424,6 +3740,11 @@
}
}
},
+ "node_modules/@radix-ui/rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
+ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="
+ },
"node_modules/@react-aria/focus": {
"version": "3.18.4",
"resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.4.tgz",
@@ -5272,6 +5593,17 @@
"node": ">=14.0.0"
}
},
+ "node_modules/aria-hidden": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
+ "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/array-buffer-byte-length": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
@@ -6737,6 +7069,11 @@
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"dev": true
},
+ "node_modules/detect-node-es": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
+ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="
+ },
"node_modules/detective-amd": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-6.0.0.tgz",
@@ -8409,6 +8746,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-nonce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
+ "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/get-own-enumerable-property-symbols": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
@@ -9228,6 +9573,14 @@
"node": ">= 0.10"
}
},
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/is-alphabetical": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
@@ -14672,6 +15025,73 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
},
+ "node_modules/react-remove-scroll": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz",
+ "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.6",
+ "react-style-singleton": "^2.2.1",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.0",
+ "use-sidecar": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-remove-scroll-bar": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz",
+ "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==",
+ "dependencies": {
+ "react-style-singleton": "^2.2.1",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/react-style-singleton": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
+ "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==",
+ "dependencies": {
+ "get-nonce": "^1.0.0",
+ "invariant": "^2.2.4",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-webcam": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/react-webcam/-/react-webcam-7.2.0.tgz",
@@ -17557,6 +17977,26 @@
"requires-port": "^1.0.0"
}
},
+ "node_modules/use-callback-ref": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz",
+ "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==",
+ "dependencies": {
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/use-keyboard-shortcut": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/use-keyboard-shortcut/-/use-keyboard-shortcut-1.1.6.tgz",
@@ -17574,6 +18014,27 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
+ "node_modules/use-sidecar": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz",
+ "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==",
+ "dependencies": {
+ "detect-node-es": "^1.1.0",
+ "tslib": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/use-sync-external-store": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
diff --git a/package.json b/package.json
index 7749374be44..57d0c3d3405 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,8 @@
"prepare": "husky install",
"lint": "eslint ./src",
"lint-fix": "eslint ./src --fix",
- "format": "prettier ./src --write"
+ "format": "prettier ./src --write",
+ "sort-locales": "node ./scripts/sort-locales.js"
},
"dependencies": {
"@fontsource/figtree": "^5.1.0",
@@ -57,9 +58,11 @@
"@hello-pangea/dnd": "^17.0.0",
"@pnotify/core": "^5.2.0",
"@pnotify/mobile": "^5.2.0",
+ "@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-toast": "^1.2.2",
+ "@radix-ui/react-tooltip": "^1.1.3",
"@sentry/browser": "^8.33.0",
"@yudiel/react-qr-scanner": "^2.0.8",
"axios": "^1.7.7",
@@ -161,10 +164,13 @@
"prettier --write --ignore-unknown --plugin prettier-plugin-tailwindcss",
"eslint --fix",
"git update-index --again"
+ ],
+ "src/Locale/*.json": [
+ "npm run sort-locales"
]
},
"engines": {
"node": ">=20.12.0"
},
"packageManager": "npm@10.5.0"
-}
+}
\ No newline at end of file
diff --git a/public/favicon.ico b/public/favicon.ico
index 67a5686e32f..51fe5064a91 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/scripts/sort-locales.js b/scripts/sort-locales.js
new file mode 100644
index 00000000000..adff586a93b
--- /dev/null
+++ b/scripts/sort-locales.js
@@ -0,0 +1,15 @@
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const fs = require("fs");
+
+const file = "src/Locale/en.json";
+
+const data = JSON.parse(fs.readFileSync(file, "utf8"));
+
+const sortedData = Object.keys(data)
+ .sort()
+ .reduce((acc, key) => {
+ acc[key] = data[key];
+ return acc;
+ }, {});
+
+fs.writeFileSync(file, JSON.stringify(sortedData, null, 2) + "\n");
diff --git a/src/CAREUI/display/Count.tsx b/src/CAREUI/display/Count.tsx
index 997b58794eb..6b28ca4f962 100644
--- a/src/CAREUI/display/Count.tsx
+++ b/src/CAREUI/display/Count.tsx
@@ -11,15 +11,13 @@ interface Props {
export default function CountBlock(props: Props) {
return (
-
-
-
+
+
+
-
-
+
-
{props.text}
{props.loading ? (
diff --git a/src/CAREUI/icons/UniconPaths.json b/src/CAREUI/icons/UniconPaths.json
index 1a76c51570d..64f97d72d65 100644
--- a/src/CAREUI/icons/UniconPaths.json
+++ b/src/CAREUI/icons/UniconPaths.json
@@ -247,6 +247,10 @@
24,
"M7,11H17a1,1,0,0,0,0-2H13V5.41l.79.8a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42l-2.5-2.5a1,1,0,0,0-.33-.21,1,1,0,0,0-.76,0,1,1,0,0,0-.33.21l-2.5,2.5a1,1,0,0,0,1.42,1.42l.79-.8V9H7a1,1,0,0,0,0,2Zm10,2H7a1,1,0,0,0,0,2h4v3.59l-.79-.8a1,1,0,0,0-1.42,1.42l2.5,2.5a1,1,0,0,0,.33.21.94.94,0,0,0,.76,0,1,1,0,0,0,.33-.21l2.5-2.5a1,1,0,0,0-1.42-1.42l-.79.8V15h4a1,1,0,0,0,0-2Z"
],
+ "l-arrow-bar-right": [
+ 24,
+ "M8.4 12c0 .4.3.7.7.7h8.3l-3.1 3.1c-.3.3-.3.7 0 1s.7.3 1 0l4.3-4.3c.3-.3.3-.7 0-1 0 0 0 0 0 0l-4.3-4.3c-.3-.3-.7-.3-1 0s-.3.7 0 1l3.1 3.1h-8.3c-.4 0-.7.3-.7.7M4.9 22c-.4 0-.7-.3-.7-.7V2.7c0-.4.3-.7.7-.7s.7.3.7.7v18.6c0 .4-.3.7-.7.7"
+ ],
"l-arrow-circle-down": [
24,
"M11.29,15.71a1,1,0,0,0,.33.21,1,1,0,0,0,.76,0,1,1,0,0,0,.33-.21l3-3a1,1,0,0,0-1.42-1.42L13,12.59V9a1,1,0,0,0-2,0v3.59l-1.29-1.3a1,1,0,0,0-1.42,0,1,1,0,0,0,0,1.42ZM12,22A10,10,0,1,0,2,12,10,10,0,0,0,12,22ZM12,4a8,8,0,1,1-8,8A8,8,0,0,1,12,4Z"
@@ -2795,6 +2799,14 @@
24,
"M2.5,10.56l9,5.2a1,1,0,0,0,1,0l9-5.2a1,1,0,0,0,0-1.73l-9-5.2a1,1,0,0,0-1,0l-9,5.2a1,1,0,0,0,0,1.73ZM12,5.65l7,4-7,4.05L5,9.69Zm8.5,7.79L12,18.35,3.5,13.44a1,1,0,0,0-1.37.36,1,1,0,0,0,.37,1.37l9,5.2a1,1,0,0,0,1,0l9-5.2a1,1,0,0,0,.37-1.37A1,1,0,0,0,20.5,13.44Z"
],
+ "l-layout-sidebar": [
+ 24,
+ "M0 4.5C0 2.8 1.3 1.5 3 1.5h18c1.7 0 3 1.3 3 3v15c0 1.7-1.3 3-3 3H3c-1.7 0-3-1.3-3-3V4.5ZM7.5 3v18h13.5c.8 0 1.5-.7 1.5-1.5V4.5c0-.8-.7-1.5-1.5-1.5H7.5ZM6 3h-3c-.8 0-1.5.7-1.5 1.5v15c0 .8.7 1.5 1.5 1.5h3V3Z"
+ ],
+ "l-layout-sidebar-alt": [
+ 24,
+ "M21 1.5H3C1.3 1.5 0 2.8 0 4.5v15c0 1.7 1.3 3 3 3h18c1.7 0 3-1.3 3-3V4.5c0-1.7-1.3-3-3-3ZM22.5 19.5c0 .8-.7 1.5-1.5 1.5H3c-.8 0-1.5-.7-1.5-1.5V4.5c0-.8.7-1.5 1.5-1.5h18c.8 0 1.5.7 1.5 1.5v15ZM10.5 6v12c0 .8-.7 1.5-1.5 1.5h-3c-.8 0-1.5-.7-1.5-1.5V6c0-.8.7-1.5 1.5-1.5h3c.8 0 1.5.7 1.5 1.5Z"
+ ],
"l-left-arrow-from-left": [
24,
"M17,11H5.41l2.3-2.29A1,1,0,1,0,6.29,7.29l-4,4a1,1,0,0,0-.21.33,1,1,0,0,0,0,.76,1,1,0,0,0,.21.33l4,4a1,1,0,0,0,1.42,0,1,1,0,0,0,0-1.42L5.41,13H17a1,1,0,0,0,0-2Zm4-7a1,1,0,0,0-1,1V19a1,1,0,0,0,2,0V5A1,1,0,0,0,21,4Z"
diff --git a/src/Components/Common/Avatar.tsx b/src/Components/Common/Avatar.tsx
index a519901216b..e4d42dd72ae 100644
--- a/src/Components/Common/Avatar.tsx
+++ b/src/Components/Common/Avatar.tsx
@@ -1,4 +1,5 @@
-import React from "react";
+import { cn } from "@/lib/utils";
+import React, { useEffect, useRef, useState } from "react";
const colors: string[] = [
"#E6F3FF", // Light Blue
@@ -44,43 +45,54 @@ const initials = (name: string): string => {
interface AvatarProps {
colors?: [string, string];
name: string;
+ imageUrl?: string;
className?: string;
- square?: boolean; // New prop to determine if the avatar should be square
}
const Avatar: React.FC = ({
colors: propColors,
name,
+ imageUrl,
className,
- square = false, // Default to false for backwards compatibility
}) => {
- const [bgColor, fgColor] = propColors || toColor(name);
+ const [bgColor] = propColors || toColor(name);
+ const [width, setWidth] = useState(0);
+ const avatarRef = useRef(null);
+
+ useEffect(() => {
+ const updateWidth = () => {
+ const avatarRect = avatarRef.current?.getBoundingClientRect();
+ const width = avatarRect?.width || 0;
+ setWidth(width);
+ };
+ updateWidth();
+ document.addEventListener("resize", updateWidth);
+ return () => document.removeEventListener("resize", updateWidth);
+ }, []);
return (
-
+
);
};
diff --git a/src/Components/Common/BloodPressureFormField.tsx b/src/Components/Common/BloodPressureFormField.tsx
index e6fff756d0f..beddd34cf38 100644
--- a/src/Components/Common/BloodPressureFormField.tsx
+++ b/src/Components/Common/BloodPressureFormField.tsx
@@ -1,13 +1,13 @@
import { useTranslation } from "react-i18next";
import { FieldValidator } from "../Form/FieldValidators";
import FormField from "../Form/FormFields/FormField";
-import RangeAutocompleteFormField from "../Form/FormFields/RangeAutocompleteFormField";
import {
FieldChangeEvent,
FormFieldBaseProps,
useFormFieldPropsResolver,
} from "../Form/FormFields/Utils";
import { BloodPressure } from "../Patient/models";
+import TextFormField from "../Form/FormFields/TextFormField";
type Props = FormFieldBaseProps;
@@ -16,12 +16,13 @@ export default function BloodPressureFormField(props: Props) {
const field = useFormFieldPropsResolver(props);
const map = meanArterialPressure(props.value)?.toFixed();
- const handleChange = (event: FieldChangeEvent) => {
+ const handleChange = (event: FieldChangeEvent) => {
+ const value = event.value ? parseInt(event.value, 10) : "";
const bp = {
systolic: field.value?.systolic,
diastolic: field.value?.diastolic,
};
- bp[event.name as keyof BloodPressure] = event.value;
+ bp[event.name as keyof BloodPressure] = value || undefined;
field.handleChange(Object.values(bp).filter(Boolean).length ? bp : null);
};
@@ -32,63 +33,35 @@ export default function BloodPressureFormField(props: Props) {
labelSuffix: map && MAP: {map},
}}
>
-
-
+
- /
- /
+
@@ -102,14 +75,20 @@ export const meanArterialPressure = (bp?: BloodPressure | null) => {
return (2 * bp.diastolic + bp.systolic) / 3;
};
-export const BloodPressureValidator: FieldValidator = (bp) => {
+export const BloodPressureValidator: FieldValidator = (
+ bp,
+ t,
+) => {
if (Object.values(bp).every((v) => v == null)) {
return;
}
- if (bp.diastolic == null) {
- return "Diastolic is missing. Either specify both or clear both.";
+ if (bp.systolic == null || bp.diastolic == null) {
+ return t("blood_pressure_error.missing");
+ }
+ if (bp.systolic > 250 || bp.diastolic > 250) {
+ return t("blood_pressure_error.exceed");
}
- if (bp.systolic == null) {
- return "Systolic is missing. Either specify both or clear both.";
+ if (bp.systolic < bp.diastolic) {
+ return t("blood_pressure_error.systolic_less_than_diastolic");
}
};
diff --git a/src/Components/Common/Breadcrumbs.tsx b/src/Components/Common/Breadcrumbs.tsx
index aaee7ac0b64..be35cf6862d 100644
--- a/src/Components/Common/Breadcrumbs.tsx
+++ b/src/Components/Common/Breadcrumbs.tsx
@@ -63,7 +63,7 @@ export default function Breadcrumbs({
return (
-
@@ -90,7 +90,7 @@ export default function Breadcrumbs({
-