diff --git a/cypress/e2e/assets_spec/assets_manage.cy.ts b/cypress/e2e/assets_spec/assets_manage.cy.ts index f27fd302a0c..1f89facd0a3 100644 --- a/cypress/e2e/assets_spec/assets_manage.cy.ts +++ b/cypress/e2e/assets_spec/assets_manage.cy.ts @@ -1,10 +1,17 @@ import { afterEach, before, beforeEach, cy, describe, it } from "local-cypress"; import { AssetPage } from "../../pageobject/Asset/AssetCreation"; import LoginPage from "../../pageobject/Login/LoginPage"; +import { AssetSearchPage } from "../../pageobject/Asset/AssetSearch"; +import FacilityPage from "../../pageobject/Facility/FacilityCreation"; +import { AssetFilters } from "../../pageobject/Asset/AssetFilters"; describe("Asset", () => { const assetPage = new AssetPage(); const loginPage = new LoginPage(); + const facilityPage = new FacilityPage(); + const assetSearchPage = new AssetSearchPage(); + const assetFilters = new AssetFilters(); + const fillFacilityName = "Dummy Facility 1"; before(() => { loginPage.loginAsDisctrictAdmin(); @@ -23,6 +30,23 @@ describe("Asset", () => { assetPage.verifyDeleteStatus(); }); + it("Verify Facility Asset Page Redirection", () => { + cy.visit("/facility"); + assetSearchPage.typeSearchKeyword(fillFacilityName); + assetSearchPage.pressEnter(); + facilityPage.verifyFacilityBadgeContent(fillFacilityName); + facilityPage.visitAlreadyCreatedFacility(); + facilityPage.clickManageFacilityDropdown(); + facilityPage.clickCreateAssetFacilityOption(); + facilityPage.verifyfacilitycreateassetredirection(); + facilityPage.verifyassetfacilitybackredirection(); + facilityPage.clickManageFacilityDropdown(); + facilityPage.clickviewAssetFacilityOption(); + facilityPage.verifyfacilityviewassetredirection(); + assetFilters.assertFacilityText(fillFacilityName); + facilityPage.verifyassetfacilitybackredirection(); + }); + afterEach(() => { cy.saveLocalStorage(); }); diff --git a/cypress/pageobject/Facility/FacilityCreation.ts b/cypress/pageobject/Facility/FacilityCreation.ts index ef4e65781e0..0c12d4655fd 100644 --- a/cypress/pageobject/Facility/FacilityCreation.ts +++ b/cypress/pageobject/Facility/FacilityCreation.ts @@ -120,6 +120,14 @@ class FacilityPage { cy.get("#configure-facility").contains("Configure Facility").click(); } + clickCreateAssetFacilityOption() { + cy.get("#create-assets").contains("Create Asset").click(); + } + + clickviewAssetFacilityOption() { + cy.get("#view-assets").contains("View Assets").click(); + } + clickInventoryManagementOption() { cy.get("#inventory-management", { timeout: 10000 }).should("be.visible"); cy.get("#inventory-management").click(); @@ -175,6 +183,33 @@ class FacilityPage { cy.wait("@getFacilities").its("response.statusCode").should("eq", 200); } + verifyFacilityBadgeContent(expectedText: string) { + cy.get("[data-testid='Facility/District Name']").should( + "contain", + expectedText + ); + } + + verifyfacilitycreateassetredirection() { + cy.intercept("GET", "**/api/v1/facility/**").as("getNewAssets"); + cy.url().should("include", "/assets/new"); + cy.wait("@getNewAssets").its("response.statusCode").should("eq", 200); + } + + verifyassetfacilitybackredirection() { + cy.intercept("GET", "**/api/v1/facility/**").as("getManagePage"); + cy.go("back"); + cy.wait("@getManagePage").its("response.statusCode").should("eq", 200); + cy.get("#manage-facility-dropdown").scrollIntoView(); + cy.get("#manage-facility-dropdown").should("exist"); + } + + verifyfacilityviewassetredirection() { + cy.intercept("GET", "**api/v1/getallfacilities/**").as("getViewAssets"); + cy.url().should("include", "/assets?facility="); + cy.wait("@getViewAssets").its("response.statusCode").should("eq", 200); + } + clickManageInventory() { cy.contains("Manage Inventory").click(); } diff --git a/package-lock.json b/package-lock.json index db11b8c5220..6f655932fd7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,6 @@ "events": "^3.3.0", "i18next": "^23.2.7", "i18next-browser-languagedetector": "^7.1.0", - "libphonenumber-js": "^1.10.37", "lodash": "^4.17.21", "postcss-loader": "^7.3.3", "qrcode.react": "^3.1.0", @@ -12079,11 +12078,6 @@ "node": ">= 0.8.0" } }, - "node_modules/libphonenumber-js": { - "version": "1.10.37", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.37.tgz", - "integrity": "sha512-Z10PCaOCiAxbUxLyR31DNeeNugSVP6iv/m7UrSKS5JHziEMApJtgku4e9Q69pzzSC9LnQiM09sqsGf2ticZnMw==" - }, "node_modules/lilconfig": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", diff --git a/package.json b/package.json index 2e894f22288..8ade8c604be 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "events": "^3.3.0", "i18next": "^23.2.7", "i18next-browser-languagedetector": "^7.1.0", - "libphonenumber-js": "^1.10.37", "lodash": "^4.17.21", "postcss-loader": "^7.3.3", "qrcode.react": "^3.1.0", diff --git a/src/Common/constants.tsx b/src/Common/constants.tsx index f5801e97e4b..f64a9fa27ae 100644 --- a/src/Common/constants.tsx +++ b/src/Common/constants.tsx @@ -1,9 +1,9 @@ import { IConfig } from "./hooks/useConfig"; import { PatientCategory } from "../Components/Facility/models"; import { SortOption } from "../Components/Common/SortDropdown"; -import { parsePhoneNumberFromString } from "libphonenumber-js"; import { dateQueryString } from "../Utils/utils"; import { IconName } from "../CAREUI/icons/CareIcon"; +import { PhoneNumberValidator } from "../Components/Form/FieldValidators"; export const RESULTS_PER_PAGE_LIMIT = 14; export const PAGINATION_LIMIT = 36; @@ -663,22 +663,22 @@ export const NURSING_CARE_FIELDS: Array = [ export const EYE_OPEN_SCALE = [ { value: 4, text: "Spontaneous" }, { value: 3, text: "To Speech" }, - { value: 2, text: "Pain" }, - { value: 1, text: "None" }, + { value: 2, text: "To Pain" }, + { value: 1, text: "No Response" }, ]; export const VERBAL_RESPONSE_SCALE = [ - { value: 5, text: "Oriented/Coos/Babbles" }, + { value: 5, text: "Oriented to Time, Place and Person" }, { value: 4, text: "Confused/Irritable" }, { value: 3, text: "Inappropriate words/Cry to Pain" }, { value: 2, text: "Incomprehensible words/Moans to pain" }, - { value: 1, text: "None" }, + { value: 1, text: "No Response" }, ]; export const MOTOR_RESPONSE_SCALE = [ - { value: 6, text: "Obeying commands" }, - { value: 5, text: "Moves to localised pain" }, - { value: 4, text: "Flexion withdrawal from pain" }, + { value: 6, text: "Obeying commands/Normal acrivity" }, + { value: 5, text: "Moves to localized pain" }, + { value: 4, text: "Flexion/Withdrawal from pain" }, { value: 3, text: "Abnormal Flexion(decorticate)" }, { value: 2, text: "Abnormal Extension(decerebrate)" }, { value: 1, text: "No Response" }, @@ -938,13 +938,12 @@ export const XLSXAssetImportSchema = { prop: "support_phone", type: String, parse: (phone: number | string) => { - const parsed = parsePhoneNumberFromString(String(phone), "IN"); - - if (!parsed?.isValid()) { + phone = "+91" + String(phone); + if (!PhoneNumberValidator(["support"])(phone) === undefined) { throw new Error("Invalid Support Phone Number"); } - return parsed?.format("E.164"); + return phone ? phone : undefined; }, required: true, }, @@ -1001,3 +1000,126 @@ export const XLSXAssetImportSchema = { }, }, }; + +export const AREACODES: Record = { + CA: [ + "403", + "587", + "250", + "604", + "778", + "204", + "431", + "506", + "709", + "867", + "902", + "226", + "249", + "289", + "343", + "365", + "416", + "437", + "519", + "613", + "647", + "705", + "807", + "902", + "418", + "438", + "450", + "514", + "579", + "581", + "819", + "306", + "639", + "867", + ], + JM: ["658", "876"], + PR: ["787", "939"], + DO: ["809", "829"], + RE: ["262", "263", "692", "693"], + YT: ["269", "639"], + CC: ["89162"], + CX: ["89164"], + BQ: ["9"], + KZ: ["6", "7"], + SJ: ["79"], +}; + +export const IN_LANDLINE_AREA_CODES = [ + "11", + "22", + "33", + "44", + "20", + "40", + "79", + "80", + "120", + "124", + "129", + "135", + "141", + "160", + "161", + "172", + "175", + "181", + "183", + "233", + "240", + "241", + "250", + "251", + "253", + "257", + "260", + "261", + "265", + "343", + "413", + "422", + "431", + "435", + "452", + "462", + "471", + "474", + "477", + "478", + "481", + "484", + "485", + "487", + "490", + "497", + "512", + "522", + "532", + "542", + "551", + "562", + "581", + "591", + "621", + "612", + "641", + "657", + "712", + "721", + "724", + "751", + "761", + "821", + "824", + "831", + "836", + "866", + "870", + "891", + "4822", +]; diff --git a/src/Common/static/countryPhoneAndFlags.json b/src/Common/static/countryPhoneAndFlags.json index 9b2ea40427d..87d963444b5 100644 --- a/src/Common/static/countryPhoneAndFlags.json +++ b/src/Common/static/countryPhoneAndFlags.json @@ -2,20 +2,20 @@ "AD": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฉ", "name": "Andorra", "code": "376" }, "AE": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ช", "name": "United Arab Emirates", "code": "971" }, "AF": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ซ", "name": "Afghanistan", "code": "93" }, - "AG": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฌ", "name": "Antigua & Barbuda", "code": "+1-268" }, - "AI": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฎ", "name": "Anguilla", "code": "+1-264" }, + "AG": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฌ", "name": "Antigua & Barbuda", "code": "1-268" }, + "AI": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฎ", "name": "Anguilla", "code": "1-264" }, "AL": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฑ", "name": "Albania", "code": "355" }, "AM": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฒ", "name": "Armenia", "code": "374" }, "AO": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ด", "name": "Angola", "code": "244" }, "AR": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ท", "name": "Argentina", "code": "54" }, - "AS": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ธ", "name": "American Samoa", "code": "+1-684" }, + "AS": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ธ", "name": "American Samoa", "code": "1-684" }, "AT": { "flag": "๐Ÿ‡ฆ๐Ÿ‡น", "name": "Austria", "code": "43" }, "AU": { "flag": "๐Ÿ‡ฆ๐Ÿ‡บ", "name": "Australia", "code": "61" }, "AW": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ผ", "name": "Aruba", "code": "297" }, - "AX": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฝ", "name": "ร…land Islands", "code": "+358-18" }, + "AX": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฝ", "name": "ร…land Islands", "code": "358-18" }, "AZ": { "flag": "๐Ÿ‡ฆ๐Ÿ‡ฟ", "name": "Azerbaijan", "code": "994" }, "BA": { "flag": "๐Ÿ‡ง๐Ÿ‡ฆ", "name": "Bosnia & Herzegovina", "code": "387" }, - "BB": { "flag": "๐Ÿ‡ง๐Ÿ‡ง", "name": "Barbados", "code": "+1-246" }, + "BB": { "flag": "๐Ÿ‡ง๐Ÿ‡ง", "name": "Barbados", "code": "1-246" }, "BD": { "flag": "๐Ÿ‡ง๐Ÿ‡ฉ", "name": "Bangladesh", "code": "880" }, "BE": { "flag": "๐Ÿ‡ง๐Ÿ‡ช", "name": "Belgium", "code": "32" }, "BF": { "flag": "๐Ÿ‡ง๐Ÿ‡ซ", "name": "Burkina Faso", "code": "226" }, @@ -24,12 +24,12 @@ "BI": { "flag": "๐Ÿ‡ง๐Ÿ‡ฎ", "name": "Burundi", "code": "257" }, "BJ": { "flag": "๐Ÿ‡ง๐Ÿ‡ฏ", "name": "Benin", "code": "229" }, "BL": { "flag": "๐Ÿ‡ง๐Ÿ‡ฑ", "name": "St. Barthรฉlemy", "code": "590" }, - "BM": { "flag": "๐Ÿ‡ง๐Ÿ‡ฒ", "name": "Bermuda", "code": "+1-441" }, + "BM": { "flag": "๐Ÿ‡ง๐Ÿ‡ฒ", "name": "Bermuda", "code": "1-441" }, "BN": { "flag": "๐Ÿ‡ง๐Ÿ‡ณ", "name": "Brunei", "code": "673" }, "BO": { "flag": "๐Ÿ‡ง๐Ÿ‡ด", "name": "Bolivia", "code": "591" }, "BQ": { "flag": "๐Ÿ‡ง๐Ÿ‡ถ", "name": "Caribbean Netherlands", "code": "599" }, "BR": { "flag": "๐Ÿ‡ง๐Ÿ‡ท", "name": "Brazil", "code": "55" }, - "BS": { "flag": "๐Ÿ‡ง๐Ÿ‡ธ", "name": "Bahamas", "code": "+1-242" }, + "BS": { "flag": "๐Ÿ‡ง๐Ÿ‡ธ", "name": "Bahamas", "code": "1-242" }, "BT": { "flag": "๐Ÿ‡ง๐Ÿ‡น", "name": "Bhutan", "code": "975" }, "BW": { "flag": "๐Ÿ‡ง๐Ÿ‡ผ", "name": "Botswana", "code": "267" }, "BY": { "flag": "๐Ÿ‡ง๐Ÿ‡พ", "name": "Belarus", "code": "375" }, @@ -56,11 +56,11 @@ "DE": { "flag": "๐Ÿ‡ฉ๐Ÿ‡ช", "name": "Germany", "code": "49" }, "DJ": { "flag": "๐Ÿ‡ฉ๐Ÿ‡ฏ", "name": "Djibouti", "code": "253" }, "DK": { "flag": "๐Ÿ‡ฉ๐Ÿ‡ฐ", "name": "Denmark", "code": "45" }, - "DM": { "flag": "๐Ÿ‡ฉ๐Ÿ‡ฒ", "name": "Dominica", "code": "+1-767" }, + "DM": { "flag": "๐Ÿ‡ฉ๐Ÿ‡ฒ", "name": "Dominica", "code": "1-767" }, "DO": { "flag": "๐Ÿ‡ฉ๐Ÿ‡ด", "name": "Dominican Republic", - "code": "+1-809 and 1-829" + "code": "1" }, "DZ": { "flag": "๐Ÿ‡ฉ๐Ÿ‡ฟ", "name": "Algeria", "code": "213" }, "EC": { "flag": "๐Ÿ‡ช๐Ÿ‡จ", "name": "Ecuador", "code": "593" }, @@ -78,10 +78,10 @@ "FR": { "flag": "๐Ÿ‡ซ๐Ÿ‡ท", "name": "France", "code": "33" }, "GA": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ฆ", "name": "Gabon", "code": "241" }, "GB": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ง", "name": "United Kingdom", "code": "44" }, - "GD": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ฉ", "name": "Grenada", "code": "+1-473" }, + "GD": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ฉ", "name": "Grenada", "code": "1-473" }, "GE": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ช", "name": "Georgia", "code": "995" }, "GF": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ซ", "name": "French Guiana", "code": "594" }, - "GG": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ฌ", "name": "Guernsey", "code": "+44-1481" }, + "GG": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ฌ", "name": "Guernsey", "code": "44-1481" }, "GH": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ญ", "name": "Ghana", "code": "233" }, "GI": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ฎ", "name": "Gibraltar", "code": "350" }, "GL": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ฑ", "name": "Greenland", "code": "299" }, @@ -91,7 +91,7 @@ "GQ": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ถ", "name": "Equatorial Guinea", "code": "240" }, "GR": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ท", "name": "Greece", "code": "30" }, "GT": { "flag": "๐Ÿ‡ฌ๐Ÿ‡น", "name": "Guatemala", "code": "502" }, - "GU": { "flag": "๐Ÿ‡ฌ๐Ÿ‡บ", "name": "Guam", "code": "+1-671" }, + "GU": { "flag": "๐Ÿ‡ฌ๐Ÿ‡บ", "name": "Guam", "code": "1-671" }, "GW": { "flag": "๐Ÿ‡ฌ๐Ÿ‡ผ", "name": "Guinea-Bissau", "code": "245" }, "GY": { "flag": "๐Ÿ‡ฌ๐Ÿ‡พ", "name": "Guyana", "code": "592" }, "HK": { "flag": "๐Ÿ‡ญ๐Ÿ‡ฐ", "name": "Hong Kong SAR China", "code": "852" }, @@ -103,7 +103,7 @@ "ID": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ฉ", "name": "Indonesia", "code": "62" }, "IE": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ช", "name": "Ireland", "code": "353" }, "IL": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ฑ", "name": "Israel", "code": "972" }, - "IM": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ฒ", "name": "Isle of Man", "code": "+44-1624" }, + "IM": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ฒ", "name": "Isle of Man", "code": "44-1624" }, "IN": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ณ", "name": "India", "code": "91" }, "IO": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ด", @@ -114,8 +114,8 @@ "IR": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ท", "name": "Iran", "code": "98" }, "IS": { "flag": "๐Ÿ‡ฎ๐Ÿ‡ธ", "name": "Iceland", "code": "354" }, "IT": { "flag": "๐Ÿ‡ฎ๐Ÿ‡น", "name": "Italy", "code": "39" }, - "JE": { "flag": "๐Ÿ‡ฏ๐Ÿ‡ช", "name": "Jersey", "code": "+44-1534" }, - "JM": { "flag": "๐Ÿ‡ฏ๐Ÿ‡ฒ", "name": "Jamaica", "code": "+1-876" }, + "JE": { "flag": "๐Ÿ‡ฏ๐Ÿ‡ช", "name": "Jersey", "code": "44-1534" }, + "JM": { "flag": "๐Ÿ‡ฏ๐Ÿ‡ฒ", "name": "Jamaica", "code": "1" }, "JO": { "flag": "๐Ÿ‡ฏ๐Ÿ‡ด", "name": "Jordan", "code": "962" }, "JP": { "flag": "๐Ÿ‡ฏ๐Ÿ‡ต", "name": "Japan", "code": "81" }, "KE": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ช", "name": "Kenya", "code": "254" }, @@ -123,15 +123,15 @@ "KH": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ญ", "name": "Cambodia", "code": "855" }, "KI": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ฎ", "name": "Kiribati", "code": "686" }, "KM": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ฒ", "name": "Comoros", "code": "269" }, - "KN": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ณ", "name": "St. Kitts & Nevis", "code": "+1-869" }, + "KN": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ณ", "name": "St. Kitts & Nevis", "code": "1-869" }, "KP": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ต", "name": "North Korea", "code": "850" }, "KR": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ท", "name": "South Korea", "code": "82" }, "KW": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ผ", "name": "Kuwait", "code": "965" }, - "KY": { "flag": "๐Ÿ‡ฐ๐Ÿ‡พ", "name": "Cayman Islands", "code": "+1-345" }, + "KY": { "flag": "๐Ÿ‡ฐ๐Ÿ‡พ", "name": "Cayman Islands", "code": "1-345" }, "KZ": { "flag": "๐Ÿ‡ฐ๐Ÿ‡ฟ", "name": "Kazakhstan", "code": "7" }, "LA": { "flag": "๐Ÿ‡ฑ๐Ÿ‡ฆ", "name": "Laos", "code": "856" }, "LB": { "flag": "๐Ÿ‡ฑ๐Ÿ‡ง", "name": "Lebanon", "code": "961" }, - "LC": { "flag": "๐Ÿ‡ฑ๐Ÿ‡จ", "name": "St. Lucia", "code": "+1-758" }, + "LC": { "flag": "๐Ÿ‡ฑ๐Ÿ‡จ", "name": "St. Lucia", "code": "1-758" }, "LI": { "flag": "๐Ÿ‡ฑ๐Ÿ‡ฎ", "name": "Liechtenstein", "code": "423" }, "LK": { "flag": "๐Ÿ‡ฑ๐Ÿ‡ฐ", "name": "Sri Lanka", "code": "94" }, "LR": { "flag": "๐Ÿ‡ฑ๐Ÿ‡ท", "name": "Liberia", "code": "231" }, @@ -152,10 +152,10 @@ "MM": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ฒ", "name": "Myanmar (Burma)", "code": "95" }, "MN": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ณ", "name": "Mongolia", "code": "976" }, "MO": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ด", "name": "Macao SAR China", "code": "853" }, - "MP": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ต", "name": "Northern Mariana Islands", "code": "+1-670" }, + "MP": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ต", "name": "Northern Mariana Islands", "code": "1-670" }, "MQ": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ถ", "name": "Martinique", "code": "596" }, "MR": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ท", "name": "Mauritania", "code": "222" }, - "MS": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ธ", "name": "Montserrat", "code": "+1-664" }, + "MS": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ธ", "name": "Montserrat", "code": "1-664" }, "MT": { "flag": "๐Ÿ‡ฒ๐Ÿ‡น", "name": "Malta", "code": "356" }, "MU": { "flag": "๐Ÿ‡ฒ๐Ÿ‡บ", "name": "Mauritius", "code": "230" }, "MV": { "flag": "๐Ÿ‡ฒ๐Ÿ‡ป", "name": "Maldives", "code": "960" }, @@ -185,7 +185,7 @@ "PL": { "flag": "๐Ÿ‡ต๐Ÿ‡ฑ", "name": "Poland", "code": "48" }, "PM": { "flag": "๐Ÿ‡ต๐Ÿ‡ฒ", "name": "St. Pierre & Miquelon", "code": "508" }, "PN": { "flag": "๐Ÿ‡ต๐Ÿ‡ณ", "name": "Pitcairn Islands", "code": "870" }, - "PR": { "flag": "๐Ÿ‡ต๐Ÿ‡ท", "name": "Puerto Rico", "code": "+1-787 and 1-939" }, + "PR": { "flag": "๐Ÿ‡ต๐Ÿ‡ท", "name": "Puerto Rico", "code": "1" }, "PS": { "flag": "๐Ÿ‡ต๐Ÿ‡ธ", "name": "Palestinian Territories", "code": "970" }, "PT": { "flag": "๐Ÿ‡ต๐Ÿ‡น", "name": "Portugal", "code": "351" }, "PW": { "flag": "๐Ÿ‡ต๐Ÿ‡ผ", "name": "Palau", "code": "680" }, @@ -214,10 +214,10 @@ "SS": { "flag": "๐Ÿ‡ธ๐Ÿ‡ธ", "name": "South Sudan", "code": "211" }, "ST": { "flag": "๐Ÿ‡ธ๐Ÿ‡น", "name": "Sรฃo Tomรฉ & Prรญncipe", "code": "239" }, "SV": { "flag": "๐Ÿ‡ธ๐Ÿ‡ป", "name": "El Salvador", "code": "503" }, - "SX": { "flag": "๐Ÿ‡ธ๐Ÿ‡ฝ", "name": "Sint Maarten", "code": "599" }, + "SX": { "flag": "๐Ÿ‡ธ๐Ÿ‡ฝ", "name": "Sint Maarten", "code": "1-721" }, "SY": { "flag": "๐Ÿ‡ธ๐Ÿ‡พ", "name": "Syria", "code": "963" }, "SZ": { "flag": "๐Ÿ‡ธ๐Ÿ‡ฟ", "name": "Eswatini", "code": "268" }, - "TC": { "flag": "๐Ÿ‡น๐Ÿ‡จ", "name": "Turks & Caicos Islands", "code": "+1-649" }, + "TC": { "flag": "๐Ÿ‡น๐Ÿ‡จ", "name": "Turks & Caicos Islands", "code": "1-649" }, "TD": { "flag": "๐Ÿ‡น๐Ÿ‡ฉ", "name": "Chad", "code": "235" }, "TG": { "flag": "๐Ÿ‡น๐Ÿ‡ฌ", "name": "Togo", "code": "228" }, "TH": { "flag": "๐Ÿ‡น๐Ÿ‡ญ", "name": "Thailand", "code": "66" }, @@ -228,7 +228,7 @@ "TN": { "flag": "๐Ÿ‡น๐Ÿ‡ณ", "name": "Tunisia", "code": "216" }, "TO": { "flag": "๐Ÿ‡น๐Ÿ‡ด", "name": "Tonga", "code": "676" }, "TR": { "flag": "๐Ÿ‡น๐Ÿ‡ท", "name": "Turkey", "code": "90" }, - "TT": { "flag": "๐Ÿ‡น๐Ÿ‡น", "name": "Trinidad & Tobago", "code": "+1-868" }, + "TT": { "flag": "๐Ÿ‡น๐Ÿ‡น", "name": "Trinidad & Tobago", "code": "1-868" }, "TV": { "flag": "๐Ÿ‡น๐Ÿ‡ป", "name": "Tuvalu", "code": "688" }, "TW": { "flag": "๐Ÿ‡น๐Ÿ‡ผ", "name": "Taiwan", "code": "886" }, "TZ": { "flag": "๐Ÿ‡น๐Ÿ‡ฟ", "name": "Tanzania", "code": "255" }, @@ -239,10 +239,10 @@ "UY": { "flag": "๐Ÿ‡บ๐Ÿ‡พ", "name": "Uruguay", "code": "598" }, "UZ": { "flag": "๐Ÿ‡บ๐Ÿ‡ฟ", "name": "Uzbekistan", "code": "998" }, "VA": { "flag": "๐Ÿ‡ป๐Ÿ‡ฆ", "name": "Vatican City", "code": "379" }, - "VC": { "flag": "๐Ÿ‡ป๐Ÿ‡จ", "name": "St. Vincent & Grenadines", "code": "+1-784" }, + "VC": { "flag": "๐Ÿ‡ป๐Ÿ‡จ", "name": "St. Vincent & Grenadines", "code": "1-784" }, "VE": { "flag": "๐Ÿ‡ป๐Ÿ‡ช", "name": "Venezuela", "code": "58" }, - "VG": { "flag": "๐Ÿ‡ป๐Ÿ‡ฌ", "name": "British Virgin Islands", "code": "+1-284" }, - "VI": { "flag": "๐Ÿ‡ป๐Ÿ‡ฎ", "name": "U.S. Virgin Islands", "code": "+1-340" }, + "VG": { "flag": "๐Ÿ‡ป๐Ÿ‡ฌ", "name": "British Virgin Islands", "code": "1-284" }, + "VI": { "flag": "๐Ÿ‡ป๐Ÿ‡ฎ", "name": "U.S. Virgin Islands", "code": "1-340" }, "VN": { "flag": "๐Ÿ‡ป๐Ÿ‡ณ", "name": "Vietnam", "code": "84" }, "VU": { "flag": "๐Ÿ‡ป๐Ÿ‡บ", "name": "Vanuatu", "code": "678" }, "WF": { "flag": "๐Ÿ‡ผ๐Ÿ‡ซ", "name": "Wallis & Futuna", "code": "681" }, diff --git a/src/Components/Assets/AssetManage.tsx b/src/Components/Assets/AssetManage.tsx index 1df9fbde9a6..27f0f2d8bc0 100644 --- a/src/Components/Assets/AssetManage.tsx +++ b/src/Components/Assets/AssetManage.tsx @@ -26,7 +26,6 @@ import { UserRole, USER_TYPES } from "../../Common/constants"; import ConfirmDialog from "../Common/ConfirmDialog"; import RecordMeta from "../../CAREUI/display/RecordMeta"; import { useTranslation } from "react-i18next"; -const PageTitle = lazy(() => import("../Common/PageTitle")); const Loading = lazy(() => import("../Common/Loading")); import * as Notification from "../../Utils/Notifications.js"; import AuthorizeFor, { NonReadOnlyUsers } from "../../Utils/AuthorizeFor"; @@ -35,6 +34,7 @@ import useAuthUser from "../../Common/hooks/useAuthUser"; import dayjs from "dayjs"; import RelativeDateUserMention from "../Common/RelativeDateUserMention"; import { AssetServiceEditModal } from "./AssetServiceEditModal"; +import Page from "../Common/components/Page"; interface AssetManageProps { assetId: string; @@ -329,18 +329,28 @@ const AssetManage = (props: AssetManageProps) => { }; return ( -
- + + + Export as JSON + + } + > { {asset?.name} - - - - Export as JSON - - +
+ + {assetClassProp.name} +
+
+
+ {asset?.description}
+ {asset?.asset_type === "INTERNAL" ? ( + + ) : ( + + )} {asset?.status === "ACTIVE" ? ( ) : ( @@ -394,7 +405,9 @@ const AssetManage = (props: AssetManageProps) => { )}
- {asset?.description} +
+ {asset?.description} +
{[ @@ -403,19 +416,6 @@ const AssetManage = (props: AssetManageProps) => { icon: "location-pin-alt", content: asset?.location_object.name, }, - { - label: "Asset Type", - icon: "apps", - content: - asset?.asset_type === "INTERNAL" - ? "Internal Asset" - : "External Asset", - }, - { - label: "Asset Class", - icon: assetClassProp.icon, - content: assetClassProp.name, - }, { label: "Asset QR Code ID", icon: "qrcode-scan", @@ -586,7 +586,7 @@ const AssetManage = (props: AssetManageProps) => { viewOnly={serviceEditData.viewOnly} /> )} -
+ ); }; diff --git a/src/Components/Assets/AssetWarrantyCard.tsx b/src/Components/Assets/AssetWarrantyCard.tsx index 5d10d4096c8..2e5fa74b9c6 100644 --- a/src/Components/Assets/AssetWarrantyCard.tsx +++ b/src/Components/Assets/AssetWarrantyCard.tsx @@ -1,36 +1,68 @@ import CareIcon from "../../CAREUI/icons/CareIcon"; import { AssetData } from "./AssetTypes"; import { classNames, formatDate } from "../../Utils/utils"; +import CopyToClipboard from "react-copy-to-clipboard"; +import { t } from "i18next"; +import { useEffect, useState } from "react"; export default function AssetWarrantyCard(props: { asset: AssetData }) { const { asset } = props; const details = { "Serial Number": asset.serial_number, - Expiry: + "Warranty/AMC Expiry": asset.warranty_amc_end_of_validity && formatDate(asset.warranty_amc_end_of_validity), Vendor: asset.vendor_name, }; + const [isCopied, setIsCopied] = useState(false); + + useEffect(() => { + if (isCopied) { + const timeout = setTimeout(() => { + setIsCopied(false); + }, 2000); + return () => clearTimeout(timeout); + } + }, [isCopied]); + return (
{asset.manufacturer}
-
-
+
+
{Object.keys(details).map((key) => (
{key}
-
+
{details[key as keyof typeof details] || "--"} + {key === "Serial Number" && ( + + )}
))}
+
diff --git a/src/Components/CriticalCareRecording/NeurologicalMonitoring/CriticalCare__NeurologicalMonitoringEditor.res b/src/Components/CriticalCareRecording/NeurologicalMonitoring/CriticalCare__NeurologicalMonitoringEditor.res index f3f789e9dcd..35d137e0414 100644 --- a/src/Components/CriticalCareRecording/NeurologicalMonitoring/CriticalCare__NeurologicalMonitoringEditor.res +++ b/src/Components/CriticalCareRecording/NeurologicalMonitoring/CriticalCare__NeurologicalMonitoringEditor.res @@ -485,7 +485,7 @@ let make = (~updateCB, ~neurologicalMonitoring, ~id, ~consultationId) => {
{str("Glasgow Coma Scale")}
-
{str("Eye Open")}
+
{str("Eye Opening Response")}
{Js.Array.mapi( (x, i) => diff --git a/src/Components/CriticalCareRecording/types/CriticalCare__NeurologicalMonitoring.res b/src/Components/CriticalCareRecording/types/CriticalCare__NeurologicalMonitoring.res index 1e8804c7524..f42ca5c140d 100644 --- a/src/Components/CriticalCareRecording/types/CriticalCare__NeurologicalMonitoring.res +++ b/src/Components/CriticalCareRecording/types/CriticalCare__NeurologicalMonitoring.res @@ -45,25 +45,25 @@ let make = ( ~limbResponseLowerExtremityRight, ~limbResponseLowerExtremityLeft, ) => { - inPronePosition: inPronePosition, - consciousnessLevel: consciousnessLevel, - consciousnessLevelDetails: consciousnessLevelDetails, - leftPupilSize: leftPupilSize, - leftPupilSizeDetails: leftPupilSizeDetails, - leftPupilLightReaction: leftPupilLightReaction, - leftPupilLightReactionDetails: leftPupilLightReactionDetails, - rightPupilSize: rightPupilSize, - rightPupilSizeDetails: rightPupilSizeDetails, - rightPupilLightReaction: rightPupilLightReaction, - rightPupilLightReactionDetails: rightPupilLightReactionDetails, - glasgowEyeOpen: glasgowEyeOpen, - glasgowVerbalResponse: glasgowVerbalResponse, - glasgowMotorResponse: glasgowMotorResponse, - glasgowTotalCalculated: glasgowTotalCalculated, - limbResponseUpperExtremityRight: limbResponseUpperExtremityRight, - limbResponseUpperExtremityLeft: limbResponseUpperExtremityLeft, - limbResponseLowerExtremityRight: limbResponseLowerExtremityRight, - limbResponseLowerExtremityLeft: limbResponseLowerExtremityLeft, + inPronePosition, + consciousnessLevel, + consciousnessLevelDetails, + leftPupilSize, + leftPupilSizeDetails, + leftPupilLightReaction, + leftPupilLightReactionDetails, + rightPupilSize, + rightPupilSizeDetails, + rightPupilLightReaction, + rightPupilLightReactionDetails, + glasgowEyeOpen, + glasgowVerbalResponse, + glasgowMotorResponse, + glasgowTotalCalculated, + limbResponseUpperExtremityRight, + limbResponseUpperExtremityLeft, + limbResponseLowerExtremityRight, + limbResponseLowerExtremityLeft, } let makeConsciousnessLevel = consciousnessLevel => { @@ -173,8 +173,8 @@ let limpResponseToString = limpResponse => { let eyeOpenToString = eyeOpen => { switch eyeOpen { - | 1 => "1 - None" - | 2 => "2 - Pain" + | 1 => "1 - No Response" + | 2 => "2 - To Pain" | 3 => "3 - To Speech" | 4 => "4 - Spontaneous" | _ => "Unknown" @@ -183,23 +183,23 @@ let eyeOpenToString = eyeOpen => { let motorResposneToString = eyeOpen => { switch eyeOpen { - | 1 => "1 - None" - | 2 => "2 - Incomprehensible words/Moans to pain" + | 1 => "1 - No Response" + | 2 => "2 - Abnormal Extension" | 3 => "3 - Abnormal Flexion" - | 4 => "4 - Withdrawing" - | 5 => "5 - Localizing/Withdrawl to touch" - | 6 => "6 - Obeying/Normal Activity" + | 4 => "4 - Flexion/Withdrawal to pain" + | 5 => "5 - Moves to localized pain" + | 6 => "6 - Obeys commands/Normal Activity" | _ => "Unknown" } } let verbalResposneToString = eyeOpen => { switch eyeOpen { - | 1 => "1 - None" + | 1 => "1 - No Response" | 2 => "2 - Incomprehensible words/Moans to pain" | 3 => "3 - Inappropriate words/Cry to pain" | 4 => "4 - Confused/Irritable" - | 5 => "5 - Oriented/Coos/Babbies" + | 5 => "5 - Oriented to Time, Place and Person" | _ => "Unknown" } } diff --git a/src/Components/ExternalResult/ResultList.tsx b/src/Components/ExternalResult/ResultList.tsx index 18de6f29134..74fbf8430b0 100644 --- a/src/Components/ExternalResult/ResultList.tsx +++ b/src/Components/ExternalResult/ResultList.tsx @@ -6,7 +6,7 @@ import { externalResultList } from "../../Redux/actions"; import ListFilter from "./ListFilter"; import FacilitiesSelectDialogue from "./FacilitiesSelectDialogue"; import { FacilityModel } from "../Facility/models"; -import parsePhoneNumberFromString from "libphonenumber-js"; +import { parsePhoneNumber } from "../../Utils/utils"; import SearchInput from "../Form/SearchInput"; import useFilters from "../../Common/hooks/useFilters"; import CareIcon from "../../CAREUI/icons/CareIcon"; @@ -65,7 +65,7 @@ export default function ResultList() { page: qParams.page || 1, name: qParams.name || "", mobile_number: qParams.mobile_number - ? parsePhoneNumberFromString(qParams.mobile_number)?.format("E.164") + ? parsePhoneNumber(qParams.mobile_number) ?? "" : "", wards: qParams.wards || undefined, local_bodies: qParams.local_bodies || undefined, diff --git a/src/Components/Facility/AssetCreate.tsx b/src/Components/Facility/AssetCreate.tsx index 1e6eead5242..156d738857a 100644 --- a/src/Components/Facility/AssetCreate.tsx +++ b/src/Components/Facility/AssetCreate.tsx @@ -30,13 +30,12 @@ import TextAreaFormField from "../Form/FormFields/TextAreaFormField"; import TextFormField from "../Form/FormFields/TextFormField"; import { navigate } from "raviger"; -import { parsePhoneNumberFromString } from "libphonenumber-js"; import { parseQueryParams } from "../../Utils/primitives"; import useAppHistory from "../../Common/hooks/useAppHistory"; import { useDispatch } from "react-redux"; import useVisibility from "../../Utils/useVisibility"; import { validateEmailAddress } from "../../Common/validation"; -import { dateQueryString } from "../../Utils/utils.js"; +import { dateQueryString, parsePhoneNumber } from "../../Utils/utils.js"; import dayjs from "../../Utils/dayjs"; import DateInputV2 from "../Common/DateInputV2.js"; @@ -341,7 +340,7 @@ const AssetCreate = (props: AssetProps) => { support_email: support_email, support_phone: support_phone.startsWith("1800") ? support_phone - : parsePhoneNumberFromString(support_phone)?.format("E.164"), + : parsePhoneNumber(support_phone), qr_code_id: qrCodeId !== "" ? qrCodeId : null, manufacturer: manufacturer, warranty_amc_end_of_validity: warranty_amc_end_of_validity diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx index affdb2756cd..490c704f295 100644 --- a/src/Components/Facility/ConsultationDetails/index.tsx +++ b/src/Components/Facility/ConsultationDetails/index.tsx @@ -402,7 +402,7 @@ export const ConsultationDetails = (props: any) => { consultationData.deprecated_verified_by) && (
- Verified By:{" "} + Treating Physician:{" "} {consultationData.verified_by_object ? `${consultationData.verified_by_object.first_name} ${consultationData.verified_by_object.last_name}` diff --git a/src/Components/Facility/ConsultationForm.tsx b/src/Components/Facility/ConsultationForm.tsx index 49028a62953..ca2301b5964 100644 --- a/src/Components/Facility/ConsultationForm.tsx +++ b/src/Components/Facility/ConsultationForm.tsx @@ -539,7 +539,7 @@ export const ConsultationForm = (props: any) => { case "verified_by": { if (state.form.suggestion !== "DD" && !state.form[field]) { - errors[field] = "Please fill verified by"; + errors[field] = "Please fill treating physician"; invalidForm = true; break; } @@ -1321,7 +1321,7 @@ export const ConsultationForm = (props: any) => { > {
Scale Description
-
Eye Open
+
+ Eye Opening Response +
{EYE_OPEN_SCALE.map((x: any) => (
{ href={`tel:${facility.phone_number}`} className="text-sm font-semibold tracking-wider" > - {parsePhoneNumber( - facility.phone_number as string, - "IN" - ).formatInternational() || "-"} + {formatPhoneNumber( + parsePhoneNumber(facility.phone_number as string) ?? "-" + )}
diff --git a/src/Components/Facility/FacilityCreate.tsx b/src/Components/Facility/FacilityCreate.tsx index d1243daaf1d..e742caefb82 100644 --- a/src/Components/Facility/FacilityCreate.tsx +++ b/src/Components/Facility/FacilityCreate.tsx @@ -26,7 +26,11 @@ import { listDoctor, updateFacility, } from "../../Redux/actions"; -import { getPincodeDetails, includesIgnoreCase } from "../../Utils/utils"; +import { + getPincodeDetails, + includesIgnoreCase, + parsePhoneNumber, +} from "../../Utils/utils"; import { phonePreg, validateLatitude, @@ -51,11 +55,11 @@ import TextAreaFormField from "../Form/FormFields/TextAreaFormField"; import TextFormField from "../Form/FormFields/TextFormField"; import { navigate } from "raviger"; -import { parsePhoneNumberFromString } from "libphonenumber-js"; import useAppHistory from "../../Common/hooks/useAppHistory"; import useConfig from "../../Common/hooks/useConfig"; import { useDispatch } from "react-redux"; import { useTranslation } from "react-i18next"; +import { PhoneNumberValidator } from "../Form/FieldValidators.js"; const Loading = lazy(() => import("../Common/Loading")); @@ -434,11 +438,11 @@ export const FacilityCreate = (props: FacilityProps) => { return; case "phone_number": // eslint-disable-next-line no-case-declarations - const phoneNumber = parsePhoneNumberFromString(state.form[field]); + const phoneNumber = state.form[field]; if ( - !state.form[field] || - !phoneNumber?.isPossible() || - !phonePreg(String(phoneNumber?.number)) + !phoneNumber || + !PhoneNumberValidator()(phoneNumber) === undefined || + !phonePreg(phoneNumber) ) { errors[field] = t("invalid_phone_number"); invalidForm = true; @@ -488,9 +492,7 @@ export const FacilityCreate = (props: FacilityProps) => { kasp_empanelled: JSON.parse(state.form.kasp_empanelled), latitude: state.form.latitude || null, longitude: state.form.longitude || null, - phone_number: parsePhoneNumberFromString( - state.form.phone_number - )?.format("E.164"), + phone_number: parsePhoneNumber(state.form.phone_number), oxygen_capacity: state.form.oxygen_capacity ? state.form.oxygen_capacity : 0, diff --git a/src/Components/Facility/FacilityHome.tsx b/src/Components/Facility/FacilityHome.tsx index 81e7fa4906f..15317b1b56c 100644 --- a/src/Components/Facility/FacilityHome.tsx +++ b/src/Components/Facility/FacilityHome.tsx @@ -575,6 +575,7 @@ export const FacilityHome = (props: any) => { Resource Request navigate(`/facility/${facilityId}/assets/new`)} authorizeFor={NonReadOnlyUsers} icon={} @@ -582,12 +583,14 @@ export const FacilityHome = (props: any) => { Create Asset navigate(`/assets?facility=${facilityId}`)} icon={} > View Assets navigate(`/facility/${facilityId}/users`)} icon={} > diff --git a/src/Components/Form/FormFields/Autocomplete.tsx b/src/Components/Form/FormFields/Autocomplete.tsx index dcf3ab5e8b6..bbc60643faf 100644 --- a/src/Components/Form/FormFields/Autocomplete.tsx +++ b/src/Components/Form/FormFields/Autocomplete.tsx @@ -157,6 +157,7 @@ export const Autocomplete = (props: AutocompleteProps) => { placeholder={props.placeholder ?? "Select"} displayValue={(value: any) => value?.label || ""} onChange={(event) => setQuery(event.target.value.toLowerCase())} + onBlur={() => value && setQuery("")} autoComplete="off" /> diff --git a/src/Components/Form/FormFields/PhoneNumberFormField.tsx b/src/Components/Form/FormFields/PhoneNumberFormField.tsx index 64c93c51500..6aa70f801de 100644 --- a/src/Components/Form/FormFields/PhoneNumberFormField.tsx +++ b/src/Components/Form/FormFields/PhoneNumberFormField.tsx @@ -1,12 +1,13 @@ import { FormFieldBaseProps, useFormFieldPropsResolver } from "./Utils"; import FormField from "./FormField"; +import { useEffect, useMemo, useState } from "react"; import { - AsYouType, - isValidPhoneNumber, + classNames, parsePhoneNumber, -} from "libphonenumber-js"; -import { useMemo, useState } from "react"; -import { classNames } from "../../../Utils/utils"; + formatPhoneNumber as formatPhoneNumberUtil, + getCountryCode, + CountryData, +} from "../../../Utils/utils"; import phoneCodesJson from "../../../Common/static/countryPhoneAndFlags.json"; import { FieldError, @@ -15,12 +16,6 @@ import { } from "../FieldValidators"; import CareIcon from "../../../CAREUI/icons/CareIcon"; -interface CountryData { - flag: string; - name: string; - code: string; -} - const phoneCodes: Record = phoneCodesJson; interface Props extends FormFieldBaseProps { @@ -39,21 +34,6 @@ export default function PhoneNumberFormField(props: Props) { [props.types] ); - const asYouType = useMemo(() => { - const asYouType = new AsYouType(); - - asYouType.reset(); - - if (field.value) { - asYouType.input(field.value); - } else { - asYouType.input("+91"); - field.handleChange(asYouType.getNumberValue()); - } - - return asYouType; - }, []); - const validate = useMemo( () => (value: string | undefined, event: "blur" | "change") => { if (!value || props.disableValidation) { @@ -73,9 +53,9 @@ export default function PhoneNumberFormField(props: Props) { const setValue = (value: string) => { value = value.replaceAll(/[^0-9+]/g, ""); - - asYouType.reset(); - asYouType.input(value); + if (value.length > 12 && value.startsWith("+910")) { + value = "+91" + value.slice(4); + } const error = validate(value, "change"); field.handleChange(value); @@ -83,6 +63,8 @@ export default function PhoneNumberFormField(props: Props) { setError(error); }; + useEffect(() => setValue(field.value || "+91"), []); + return ( setValue(e.target.value)} disabled={field.disabled} onBlur={() => setError(validate(field.value, "blur"))} @@ -122,7 +104,7 @@ export default function PhoneNumberFormField(props: Props) { autoComplete="country" className="cui-input-base h-full border-0 bg-transparent pl-2 pr-8 text-end font-medium tracking-wider text-gray-700 focus:ring-2 focus:ring-inset" value={ - asYouType.getCountry() ?? + getCountryCode(field.value) ?? (field.value?.startsWith("1800") ? "1800" : "Other") } onChange={(e) => { @@ -176,15 +158,15 @@ const conditionPhoneCode = (code: string) => { return code.startsWith("+") ? code : "+" + code; }; -const formatPhoneNumber = (value: string) => { +const formatPhoneNumber = (value: string, types: PhoneNumberType[]) => { if (value === undefined || value === null) { return "+91 "; } - if (!isValidPhoneNumber(value)) { + if (PhoneNumberValidator(types)(value) !== undefined || value.length < 13) { return value; } const phoneNumber = parsePhoneNumber(value); - return phoneNumber.formatInternational(); + return phoneNumber ? formatPhoneNumberUtil(phoneNumber) : value; }; diff --git a/src/Components/Medicine/MedibaseAutocompleteFormField.tsx b/src/Components/Medicine/MedibaseAutocompleteFormField.tsx index 337546691f9..2b5612f6f32 100644 --- a/src/Components/Medicine/MedibaseAutocompleteFormField.tsx +++ b/src/Components/Medicine/MedibaseAutocompleteFormField.tsx @@ -49,7 +49,7 @@ export default function MedibaseAutocompleteFormField( value={field.value} required onChange={field.handleChange} - options={options(field.value && [field.value])} + options={options(field.value && !query && [field.value])} optionLabel={(option) => option.name.toUpperCase()} optionDescription={(option) => } optionValue={(option) => option} diff --git a/src/Components/Patient/ManagePatients.tsx b/src/Components/Patient/ManagePatients.tsx index 54d22b5f54c..71a3ad08c8c 100644 --- a/src/Components/Patient/ManagePatients.tsx +++ b/src/Components/Patient/ManagePatients.tsx @@ -38,7 +38,7 @@ import SortDropdownMenu from "../Common/SortDropdown"; import SwitchTabs from "../Common/components/SwitchTabs"; import SwipeableViews from "react-swipeable-views"; import { parseOptionId } from "../../Common/utils"; -import { parsePhoneNumberFromString } from "libphonenumber-js"; +import { parsePhoneNumber } from "../../Utils/utils.js"; import { useDispatch } from "react-redux"; import useFilters from "../../Common/hooks/useFilters"; import { useTranslation } from "react-i18next"; @@ -161,12 +161,10 @@ export const PatientManager = () => { (qParams.is_active || "True"), disease_status: qParams.disease_status || undefined, phone_number: qParams.phone_number - ? parsePhoneNumberFromString(qParams.phone_number)?.format("E.164") + ? parsePhoneNumber(qParams.phone_number) : undefined, emergency_phone_number: qParams.emergency_phone_number - ? parsePhoneNumberFromString(qParams.emergency_phone_number)?.format( - "E.164" - ) + ? parsePhoneNumber(qParams.emergency_phone_number) : undefined, local_body: qParams.lsgBody || undefined, facility: qParams.facility, diff --git a/src/Components/Patient/PatientRegister.tsx b/src/Components/Patient/PatientRegister.tsx index d52ce840090..41f36bffd35 100644 --- a/src/Components/Patient/PatientRegister.tsx +++ b/src/Components/Patient/PatientRegister.tsx @@ -25,6 +25,7 @@ import { dateQueryString, getPincodeDetails, includesIgnoreCase, + parsePhoneNumber, } from "../../Utils/utils"; import { navigate, useQueryParams } from "raviger"; import { statusType, useAbortableEffect } from "../../Common/utils"; @@ -40,7 +41,11 @@ import DateFormField from "../Form/FormFields/DateFormField"; import DialogModal from "../Common/Dialog"; import { DupPatientModel } from "../Facility/models"; import DuplicatePatientDialog from "../Facility/DuplicatePatientDialog"; -import { FieldError, RequiredFieldValidator } from "../Form/FieldValidators"; +import { + FieldError, + PhoneNumberValidator, + RequiredFieldValidator, +} from "../Form/FieldValidators"; import { FieldErrorText, FieldLabel } from "../Form/FormFields/FormField"; import Form from "../Form/Form"; import { HCXPolicyModel } from "../HCX/models"; @@ -58,7 +63,6 @@ import TransferPatientDialog from "../Facility/TransferPatientDialog"; import countryList from "../../Common/static/countries.json"; import { debounce } from "lodash"; -import { parsePhoneNumberFromString } from "libphonenumber-js"; import useAppHistory from "../../Common/hooks/useAppHistory"; import useConfig from "../../Common/hooks/useConfig"; import { useDispatch } from "react-redux"; @@ -98,7 +102,7 @@ const initForm: any = { age: "", gender: "", phone_number: "+91", - emergency_phone_number: null, + emergency_phone_number: "+91", blood_group: "", disease_status: diseaseStatus[2], is_declared_positive: "false", @@ -596,14 +600,22 @@ export const PatientRegister = (props: PatientRegisterProps) => { } return; case "phone_number": - phoneNumber = parsePhoneNumberFromString(form[field]); - if (!form[field] || !phoneNumber?.isPossible()) { + phoneNumber = parsePhoneNumber(form[field]); + if ( + !form[field] || + !phoneNumber || + !PhoneNumberValidator()(phoneNumber) === undefined + ) { errors[field] = "Please enter valid phone number"; } return; case "emergency_phone_number": - emergency_phone_number = parsePhoneNumberFromString(form[field]); - if (!form[field] || !emergency_phone_number?.isPossible()) { + emergency_phone_number = parsePhoneNumber(form[field]); + if ( + !form[field] || + !emergency_phone_number || + !PhoneNumberValidator()(emergency_phone_number) === undefined + ) { errors[field] = "Please enter valid phone number"; } return; @@ -729,12 +741,8 @@ export const PatientRegister = (props: PatientRegisterProps) => { }); const data = { abha_number: state.form.abha_number, - phone_number: parsePhoneNumberFromString(formData.phone_number)?.format( - "E.164" - ), - emergency_phone_number: parsePhoneNumberFromString( - formData.emergency_phone_number - )?.format("E.164"), + phone_number: parsePhoneNumber(formData.phone_number), + emergency_phone_number: parsePhoneNumber(formData.emergency_phone_number), date_of_birth: dateQueryString(formData.date_of_birth), disease_status: formData.disease_status, date_of_test: formData.date_of_test ? formData.date_of_test : undefined, @@ -912,12 +920,12 @@ export const PatientRegister = (props: PatientRegisterProps) => { if (mobile) { field("phone_number").onChange({ name: "phone_number", - value: parsePhoneNumberFromString(mobile, "IN")?.format("E.164"), + value: parsePhoneNumber(mobile), }); field("emergency_phone_number").onChange({ name: "emergency_phone_number", - value: parsePhoneNumberFromString(mobile, "IN")?.format("E.164"), + value: parsePhoneNumber(mobile), }); } @@ -958,9 +966,12 @@ export const PatientRegister = (props: PatientRegisterProps) => { const duplicateCheck = useCallback( debounce(async (phoneNo: string) => { - if (phoneNo && parsePhoneNumberFromString(phoneNo)?.isPossible()) { + if ( + phoneNo && + PhoneNumberValidator()(parsePhoneNumber(phoneNo) ?? "") === undefined + ) { const query = { - phone_number: parsePhoneNumberFromString(phoneNo)?.format("E.164"), + phone_number: parsePhoneNumber(phoneNo), }; const res = await dispatchAction(searchPatient(query)); if (res?.data?.results) { diff --git a/src/Components/Patient/ShiftCreate.tsx b/src/Components/Patient/ShiftCreate.tsx index 7283fb3d5d7..e8e89ebc59c 100644 --- a/src/Components/Patient/ShiftCreate.tsx +++ b/src/Components/Patient/ShiftCreate.tsx @@ -18,7 +18,7 @@ import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField"; import TextAreaFormField from "../Form/FormFields/TextAreaFormField"; import TextFormField from "../Form/FormFields/TextFormField"; import { navigate } from "raviger"; -import { parsePhoneNumberFromString } from "libphonenumber-js"; +import { parsePhoneNumber } from "../../Utils/utils.js"; import { phonePreg } from "../../Common/validation"; import useAppHistory from "../../Common/hooks/useAppHistory"; import useConfig from "../../Common/hooks/useConfig"; @@ -28,6 +28,7 @@ import Page from "../Common/components/Page.js"; import Card from "../../CAREUI/display/Card.js"; import CheckBoxFormField from "../Form/FormFields/CheckBoxFormField.js"; import { SelectFormField } from "../Form/FormFields/SelectFormField.js"; +import { PhoneNumberValidator } from "../Form/FieldValidators.js"; const Loading = lazy(() => import("../Common/Loading")); @@ -56,13 +57,13 @@ export const ShiftCreate = (props: patientShiftProps) => { vehicle_preference: "", comments: "", refering_facility_contact_name: "", - refering_facility_contact_number: "+91", + refering_facility_contact_number: "", assigned_facility_type: null, preferred_vehicle_choice: null, breathlessness_level: null, patient_category: "", ambulance_driver_name: "", - ambulance_phone_number: undefined, + ambulance_phone_number: "", ambulance_number: "", }; @@ -162,10 +163,10 @@ export const ShiftCreate = (props: patientShiftProps) => { errors[field] = requiredFields[field].errorText; isInvalidForm = true; } else if ( - !parsePhoneNumberFromString(state.form[field])?.isPossible() || - !phonePreg( - String(parsePhoneNumberFromString(state.form[field])?.number) - ) + !PhoneNumberValidator()( + parsePhoneNumber(state.form[field]) ?? "" + ) === undefined || + !phonePreg(String(parsePhoneNumber(state.form[field]))) ) { errors[field] = requiredFields[field].invalidText; isInvalidForm = true; @@ -222,15 +223,15 @@ export const ShiftCreate = (props: patientShiftProps) => { preferred_vehicle_choice: state.form.preferred_vehicle_choice, refering_facility_contact_name: state.form.refering_facility_contact_name, - refering_facility_contact_number: parsePhoneNumberFromString( + refering_facility_contact_number: parsePhoneNumber( state.form.refering_facility_contact_number - )?.format("E.164"), + ), breathlessness_level: state.form.breathlessness_level, patient_category: patientCategory, ambulance_driver_name: state.form.ambulance_driver_name, - ambulance_phone_number: parsePhoneNumberFromString( + ambulance_phone_number: parsePhoneNumber( state.form.ambulance_phone_number - )?.format("E.164"), + ), ambulance_number: state.form.ambulance_number, }; diff --git a/src/Components/Resource/ResourceCreate.tsx b/src/Components/Resource/ResourceCreate.tsx index 417455d1ec1..cf9e5f6f22a 100644 --- a/src/Components/Resource/ResourceCreate.tsx +++ b/src/Components/Resource/ResourceCreate.tsx @@ -9,7 +9,7 @@ import { RESOURCE_CATEGORY_CHOICES, RESOURCE_SUBCATEGORIES, } from "../../Common/constants"; -import { parsePhoneNumberFromString } from "libphonenumber-js"; +import { parsePhoneNumber } from "../../Utils/utils"; import { phonePreg } from "../../Common/validation"; import { createResource, getAnyFacility } from "../../Redux/actions"; @@ -25,6 +25,7 @@ import RadioFormField from "../Form/FormFields/RadioFormField"; import { FieldLabel } from "../Form/FormFields/FormField"; import Card from "../../CAREUI/display/Card"; import Page from "../Common/components/Page"; +import { PhoneNumberValidator } from "../Form/FieldValidators"; const Loading = lazy(() => import("../Common/Loading")); @@ -41,7 +42,7 @@ const initForm: any = { title: "", reason: "", refering_facility_contact_name: "", - refering_facility_contact_number: "", + refering_facility_contact_number: "+91", required_quantity: null, }; @@ -131,13 +132,14 @@ export default function ResourceCreate(props: resourceProps) { Object.keys(requiredFields).forEach((field) => { switch (field) { case "refering_facility_contact_number": { - const phoneNumber = parsePhoneNumberFromString(state.form[field]); + const phoneNumber = parsePhoneNumber(state.form[field]); if (!state.form[field]) { errors[field] = requiredFields[field].errorText; isInvalidForm = true; } else if ( - !phoneNumber?.isPossible() || - !phonePreg(String(phoneNumber?.number)) + !phoneNumber || + !PhoneNumberValidator()(phoneNumber) === undefined || + !phonePreg(String(phoneNumber)) ) { errors[field] = requiredFields[field].invalidText; isInvalidForm = true; @@ -194,9 +196,9 @@ export default function ResourceCreate(props: resourceProps) { reason: state.form.reason, refering_facility_contact_name: state.form.refering_facility_contact_name, - refering_facility_contact_number: parsePhoneNumberFromString( + refering_facility_contact_number: parsePhoneNumber( state.form.refering_facility_contact_number - )?.format("E.164"), + ), requested_quantity: state.form.requested_quantity || 0, }; diff --git a/src/Components/Shifting/ListFilter.tsx b/src/Components/Shifting/ListFilter.tsx index afdc087973f..5f2233c2263 100644 --- a/src/Components/Shifting/ListFilter.tsx +++ b/src/Components/Shifting/ListFilter.tsx @@ -19,13 +19,12 @@ import FiltersSlideover from "../../CAREUI/interactive/FiltersSlideover"; import { SelectFormField } from "../Form/FormFields/SelectFormField"; import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField"; import { navigate } from "raviger"; -import parsePhoneNumberFromString from "libphonenumber-js"; import useConfig from "../../Common/hooks/useConfig"; import { useDispatch } from "react-redux"; import useMergeState from "../../Common/hooks/useMergeState"; import { useTranslation } from "react-i18next"; import UserAutocompleteFormField from "../Common/UserAutocompleteFormField"; -import { dateQueryString } from "../../Utils/utils"; +import { dateQueryString, parsePhoneNumber } from "../../Utils/utils"; import dayjs from "dayjs"; const clearFilterState = { @@ -207,10 +206,10 @@ export default function ListFilter(props: any) { assigned_facility: assigned_facility || "", emergency: emergency || "", is_up_shift: is_up_shift || "", - patient_phone_number: patient_phone_number - ? parsePhoneNumberFromString(patient_phone_number)?.format("E.164") ?? - "" - : "", + patient_phone_number: + patient_phone_number === "+91" + ? "" + : parsePhoneNumber(patient_phone_number) ?? "", created_date_before: dateQueryString(created_date_before), created_date_after: dateQueryString(created_date_after), modified_date_before: dateQueryString(modified_date_before), diff --git a/src/Components/Shifting/ShiftDetailsUpdate.tsx b/src/Components/Shifting/ShiftDetailsUpdate.tsx index dd10bae6a96..ec4eab661d9 100644 --- a/src/Components/Shifting/ShiftDetailsUpdate.tsx +++ b/src/Components/Shifting/ShiftDetailsUpdate.tsx @@ -23,7 +23,7 @@ import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField"; import { SelectFormField } from "../Form/FormFields/SelectFormField.js"; import TextAreaFormField from "../Form/FormFields/TextAreaFormField"; import TextFormField from "../Form/FormFields/TextFormField"; -import { parsePhoneNumberFromString } from "libphonenumber-js"; +import { parsePhoneNumber } from "../../Utils/utils.js"; import useAppHistory from "../../Common/hooks/useAppHistory"; import useConfig from "../../Common/hooks/useConfig"; import { useDispatch } from "react-redux"; @@ -222,9 +222,10 @@ export const ShiftDetailsUpdate = (props: patientShiftProps) => { breathlessness_level: state.form.breathlessness_level, patient_category: state.form.patient_category, ambulance_driver_name: state.form.ambulance_driver_name, - ambulance_phone_number: parsePhoneNumberFromString( - state.form.ambulance_phone_number - )?.format("E.164"), + ambulance_phone_number: + state.form.ambulance_phone_number === "+91" + ? "" + : parsePhoneNumber(state.form.ambulance_phone_number), ambulance_number: state.form.ambulance_number, }; diff --git a/src/Components/Users/UserAdd.tsx b/src/Components/Users/UserAdd.tsx index 18b1e9fa73d..a6553bad01b 100644 --- a/src/Components/Users/UserAdd.tsx +++ b/src/Components/Users/UserAdd.tsx @@ -1,5 +1,4 @@ import { Link, navigate } from "raviger"; -import { parsePhoneNumberFromString } from "libphonenumber-js/max"; import { lazy, useCallback, useEffect, useState } from "react"; import { useDispatch } from "react-redux"; import { @@ -25,8 +24,11 @@ import { import * as Notification from "../../Utils/Notifications.js"; import { FacilitySelect } from "../Common/FacilitySelect"; import { FacilityModel } from "../Facility/models"; - -import { classNames, dateQueryString } from "../../Utils/utils"; +import { + classNames, + dateQueryString, + parsePhoneNumber, +} from "../../Utils/utils"; import { Cancel, Submit } from "../Common/components/ButtonV2"; import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField"; import TextFormField from "../Form/FormFields/TextFormField"; @@ -42,6 +44,7 @@ import CircularProgress from "../Common/components/CircularProgress"; import { DraftSection, useAutoSaveReducer } from "../../Utils/AutoSave"; import dayjs from "../../Utils/dayjs"; import useAuthUser from "../../Common/hooks/useAuthUser"; +import { PhoneNumberValidator } from "../Form/FieldValidators"; const Loading = lazy(() => import("../Common/Loading")); @@ -472,14 +475,11 @@ export const UserAdd = (props: UserProps) => { return; case "phone_number": // eslint-disable-next-line no-case-declarations - const phoneNumber = parsePhoneNumberFromString( - state.form[field], - "IN" - ); + const phoneNumber = parsePhoneNumber(state.form[field]); // eslint-disable-next-line no-case-declarations let is_valid = false; if (phoneNumber) { - is_valid = phoneNumber.isValid(); + is_valid = PhoneNumberValidator()(phoneNumber) === undefined; } if (!state.form[field] || !is_valid) { errors[field] = "Please enter valid phone number"; @@ -491,12 +491,10 @@ export const UserAdd = (props: UserProps) => { // eslint-disable-next-line no-case-declarations let alt_is_valid = false; if (state.form[field] && state.form[field] !== "+91") { - const altPhoneNumber = parsePhoneNumberFromString( - state.form[field], - "IN" - ); + const altPhoneNumber = parsePhoneNumber(state.form[field]); if (altPhoneNumber) { - alt_is_valid = altPhoneNumber.isValid(); + alt_is_valid = + PhoneNumberValidator(["mobile"])(altPhoneNumber) === undefined; } } if ( @@ -572,15 +570,20 @@ export const UserAdd = (props: UserProps) => { state: state.form.state, district: state.form.district, local_body: showLocalbody ? state.form.local_body : null, - phone_number: parsePhoneNumberFromString( - state.form.phone_number - )?.format("E.164"), + phone_number: + state.form.phone_number === "+91" + ? "" + : parsePhoneNumber(state.form.phone_number), alt_phone_number: - parsePhoneNumberFromString( + parsePhoneNumber( state.form.phone_number_is_whatsapp - ? state.form.phone_number + ? state.form.phone_number === "+91" + ? "" + : state.form.phone_number + : state.form.alt_phone_number === "+91" + ? "" : state.form.alt_phone_number - )?.format("E.164") ?? "", + ) ?? "", date_of_birth: dateQueryString(state.form.date_of_birth), age: Number(dayjs().diff(state.form.date_of_birth, "years", false)), doctor_qualification: diff --git a/src/Components/Users/UserFilter.tsx b/src/Components/Users/UserFilter.tsx index 681b7517e04..1450e6b6f79 100644 --- a/src/Components/Users/UserFilter.tsx +++ b/src/Components/Users/UserFilter.tsx @@ -3,7 +3,7 @@ import { useDispatch } from "react-redux"; import { getDistrict } from "../../Redux/actions"; import { navigate } from "raviger"; import DistrictSelect from "../Facility/FacilityFilter/DistrictSelect"; -import parsePhoneNumberFromString from "libphonenumber-js"; +import { parsePhoneNumber } from "../../Utils/utils"; import TextFormField from "../Form/FormFields/TextFormField"; import SelectMenuV2 from "../Form/SelectMenuV2"; import { FieldLabel } from "../Form/FormFields/FormField"; @@ -14,8 +14,8 @@ import FiltersSlideover from "../../CAREUI/interactive/FiltersSlideover"; const parsePhoneNumberForFilterParam = (phoneNumber: string) => { if (!phoneNumber) return ""; - if (phoneNumber.startsWith("+")) - return parsePhoneNumberFromString(phoneNumber)?.format("E.164") || ""; + if (phoneNumber === "+91") return ""; + if (phoneNumber.startsWith("+")) return parsePhoneNumber(phoneNumber) ?? ""; return phoneNumber; }; @@ -25,8 +25,8 @@ export default function UserFilter(props: any) { const [filterState, setFilterState] = useMergeState({ first_name: filter.first_name || "", last_name: filter.last_name || "", - phone_number: filter.phone_number || undefined, - alt_phone_number: filter.alt_phone_number || undefined, + phone_number: filter.phone_number || "+91", + alt_phone_number: filter.alt_phone_number || "+91", user_type: filter.user_type || "", district_id: filter.district_id || "", district_ref: null, diff --git a/src/Components/Users/UserProfile.tsx b/src/Components/Users/UserProfile.tsx index 3fb4bccc7c7..5c5ad46b9fa 100644 --- a/src/Components/Users/UserProfile.tsx +++ b/src/Components/Users/UserProfile.tsx @@ -8,13 +8,12 @@ import { partialUpdateUser, updateUserPassword, } from "../../Redux/actions"; -import { parsePhoneNumberFromString } from "libphonenumber-js/max"; import { validateEmailAddress } from "../../Common/validation"; import * as Notification from "../../Utils/Notifications.js"; import LanguageSelector from "../../Components/Common/LanguageSelector"; import TextFormField from "../Form/FormFields/TextFormField"; import ButtonV2, { Submit } from "../Common/components/ButtonV2"; -import { classNames, handleSignOut } from "../../Utils/utils"; +import { classNames, handleSignOut, parsePhoneNumber } from "../../Utils/utils"; import CareIcon from "../../CAREUI/icons/CareIcon"; import PhoneNumberFormField from "../Form/FormFields/PhoneNumberFormField"; import { FieldChangeEvent } from "../Form/FormFields/Utils"; @@ -23,6 +22,7 @@ import { SkillModel, SkillObjectModel } from "../Users/models"; import UpdatableApp, { checkForUpdate } from "../Common/UpdatableApp"; import dayjs from "../../Utils/dayjs"; import useAuthUser from "../../Common/hooks/useAuthUser"; +import { PhoneNumberValidator } from "../Form/FieldValidators"; const Loading = lazy(() => import("../Common/Loading")); @@ -199,15 +199,12 @@ export default function UserProfile() { return; case "phoneNumber": // eslint-disable-next-line no-case-declarations - const phoneNumber = parsePhoneNumberFromString( - states.form[field], - "IN" - ); + const phoneNumber = parsePhoneNumber(states.form[field]); // eslint-disable-next-line no-case-declarations let is_valid = false; if (phoneNumber) { - is_valid = phoneNumber.isValid(); + is_valid = PhoneNumberValidator()(phoneNumber) === undefined; } if (!states.form[field] || !is_valid) { @@ -219,12 +216,10 @@ export default function UserProfile() { // eslint-disable-next-line no-case-declarations let alt_is_valid = false; if (states.form[field] && states.form[field] !== "+91") { - const altPhoneNumber = parsePhoneNumberFromString( - states.form[field], - "IN" - ); + const altPhoneNumber = parsePhoneNumber(states.form[field]); if (altPhoneNumber) { - alt_is_valid = altPhoneNumber.isValid(); + alt_is_valid = + PhoneNumberValidator(["mobile"])(altPhoneNumber) === undefined; } } @@ -300,13 +295,8 @@ export default function UserProfile() { first_name: states.form.firstName, last_name: states.form.lastName, email: states.form.email, - phone_number: parsePhoneNumberFromString( - states.form.phoneNumber - )?.format("E.164"), - alt_phone_number: - parsePhoneNumberFromString(states.form.altPhoneNumber)?.format( - "E.164" - ) || "", + phone_number: parsePhoneNumber(states.form.phoneNumber) ?? "", + alt_phone_number: parsePhoneNumber(states.form.altPhoneNumber) ?? "", gender: states.form.gender, age: states.form.age, doctor_qualification: diff --git a/src/Utils/utils.ts b/src/Utils/utils.ts index 0ccf38ee9ce..4c29d5105f3 100644 --- a/src/Utils/utils.ts +++ b/src/Utils/utils.ts @@ -1,5 +1,10 @@ import { navigate } from "raviger"; -import { LocalStorageKeys } from "../Common/constants"; +import { + AREACODES, + IN_LANDLINE_AREA_CODES, + LocalStorageKeys, +} from "../Common/constants"; +import phoneCodesJson from "../Common/static/countryPhoneAndFlags.json"; import dayjs from "./dayjs"; interface ApacheParams { @@ -240,3 +245,135 @@ export const formatCurrency = (price: number) => export const isUserOnline = (user: { last_login: DateLike }) => { return dayjs().subtract(5, "minutes").isBefore(user.last_login); }; + +export interface CountryData { + flag: string; + name: string; + code: string; +} + +export const parsePhoneNumber = (phoneNumber: string, countryCode?: string) => { + const phoneCodes: Record = phoneCodesJson; + let parsedNumber = phoneNumber.replace(/[-+() ]/g, ""); + if (countryCode && phoneCodes[countryCode]) { + parsedNumber = phoneCodes[countryCode].code + parsedNumber; + } else if (!phoneNumber.startsWith("+")) { + return undefined; + } + parsedNumber = "+" + parsedNumber; + return parsedNumber; +}; + +export const formatPhoneNumber = (phoneNumber: string) => { + if (phoneNumber.startsWith("+91")) { + phoneNumber = phoneNumber.startsWith("+910") + ? phoneNumber.slice(4) + : phoneNumber.slice(3); + const landline_code = IN_LANDLINE_AREA_CODES.find((code) => + phoneNumber.startsWith(code) + ); + if (landline_code === undefined) + return "+91" + " " + phoneNumber.slice(0, 5) + " " + phoneNumber.slice(5); + const subscriber_no_length = 10 - landline_code.length; + return ( + "+91" + + " " + + landline_code + + " " + + phoneNumber.slice( + landline_code.length, + subscriber_no_length / 2 + landline_code.length + ) + + " " + + phoneNumber.slice(subscriber_no_length / 2 + landline_code.length) + ); + } else if (phoneNumber.startsWith("1800")) { + return "1800" + " " + phoneNumber.slice(4, 7) + " " + phoneNumber.slice(7); + } else if (phoneNumber.startsWith("+")) { + const countryCode = getCountryCode(phoneNumber); + if (!countryCode) return phoneNumber; + const phoneCodes: Record = phoneCodesJson; + return ( + "+" + + phoneCodes[countryCode].code + + " " + + phoneNumber.slice(phoneCodes[countryCode].code.length + 1) + ); + } + return phoneNumber; +}; + +export const getCountryCode = (phoneNumber: string) => { + if (phoneNumber.startsWith("+")) { + const phoneCodes: Record = phoneCodesJson; + const phoneCodesArr = Object.keys(phoneCodes); + phoneNumber = phoneNumber.slice(1); + const allMatchedCountries: { name: string; code: string }[] = []; + for (let i = 0; i < phoneCodesArr.length; i++) { + if ( + phoneNumber.startsWith( + phoneCodes[phoneCodesArr[i]].code.replaceAll("-", "") + ) + ) { + allMatchedCountries.push({ + name: phoneCodesArr[i], + code: phoneCodes[phoneCodesArr[i]].code.replaceAll("-", ""), + }); + } + } + // returns the country which is longest in case there are multiple matches + if (allMatchedCountries.length === 0) return undefined; + const matchedCountry = allMatchedCountries.reduce((max, country) => + max.code > country.code ? max : country + ); + const sameCodeCountries = allMatchedCountries.filter( + (country) => country.code === matchedCountry.code + ); + if (matchedCountry === undefined) return undefined; + // some countries share same country code but differ in area codes + // The area codes are checked for such countries + if (matchedCountry.code == "1") { + const areaCode = phoneNumber.substring(1, 4); + return ( + sameCodeCountries.find((country) => + AREACODES[country.name]?.includes(areaCode) + )?.name ?? "US" + ); + } else if (matchedCountry.code === "262") { + const areaCode = phoneNumber.substring(3, 6); + return sameCodeCountries.find((country) => + AREACODES[country.name]?.includes(areaCode) + )?.name; + } else if (matchedCountry.code === "61") { + const areaCode = phoneNumber.substring(2, 7); + return ( + sameCodeCountries.find((country) => + AREACODES[country.name]?.includes(areaCode) + )?.name ?? "AU" + ); + } else if (matchedCountry.code === "599") { + const areaCode = phoneNumber.substring(3, 4); + return ( + sameCodeCountries.find((country) => + AREACODES[country.name]?.includes(areaCode) + )?.name ?? "CW" + ); + } else if (matchedCountry.code == "7") { + const areaCode = phoneNumber.substring(1, 2); + return ( + sameCodeCountries.find((country) => + AREACODES[country.name]?.includes(areaCode) + )?.name ?? "RU" + ); + } else if (matchedCountry.code == "47") { + const areaCode = phoneNumber.substring(2, 4); + return ( + sameCodeCountries.find((country) => + AREACODES[country.name]?.includes(areaCode) + )?.name ?? "NO" + ); + } + return matchedCountry.name; + } + return undefined; +};