From 1ba196a6ea7045563b3ab34e725a057bbc564549 Mon Sep 17 00:00:00 2001 From: "yedidya.freundlich" Date: Mon, 14 Mar 2022 12:24:14 +0200 Subject: [PATCH 1/5] adding donor country ID --- packages/common/src/LocaleUtils.ts | 1 + packages/common/src/Validation.ts | 19 +++++++++++++++ packages/common/src/types.ts | 1 + .../BookManualDonationScreen.tsx | 24 ++++++++++++++++--- .../BookManualDonationScreenContainer.tsx | 4 +++- 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/packages/common/src/LocaleUtils.ts b/packages/common/src/LocaleUtils.ts index 97dce2d5a..17d2f21d6 100644 --- a/packages/common/src/LocaleUtils.ts +++ b/packages/common/src/LocaleUtils.ts @@ -85,6 +85,7 @@ export const getValidationErrorTranslation = ( case PersonalDetailsValidation.PHONE_INVALID: return "מספר הטלפון אינו תקין"; case PersonalDetailsValidation.PHONE_HAS_NANS: + case PersonalDetailsValidation.ID_HAS_NANS: return "יש להזין ספרות בלבד"; case PersonalDetailsValidation.REQUIRED_FIELD: return "שדה חובה"; diff --git a/packages/common/src/Validation.ts b/packages/common/src/Validation.ts index 30b7bd84c..a76a63582 100644 --- a/packages/common/src/Validation.ts +++ b/packages/common/src/Validation.ts @@ -2,6 +2,8 @@ export enum PersonalDetailsValidation { VALID_FIELD = "VALID_FIELD", NAME_TOO_SHORT = "NAME_TOO_SHORT", FULL_NAME_TOO_LONG = "FULL_NAME_TOO_LONG", + ID_INVALID = "ID_INVALID", + ID_HAS_NANS = "ID_HAS_NANS", PHONE_INVALID = "PHONE_INVALID", PHONE_HAS_NANS = "PHONE_HAS_NANS", REQUIRED_FIELD = "REQUIRED_FIELD", @@ -20,6 +22,11 @@ export type LastNameValidation = | PersonalDetailsValidation.NAME_TOO_SHORT | PersonalDetailsValidation.FULL_NAME_TOO_LONG; +export type CountryIdNumberValidation = + PersonalDetailsValidation.VALID_FIELD + | PersonalDetailsValidation.ID_INVALID + | PersonalDetailsValidation.ID_HAS_NANS; + export type PhoneValidation = | FieldValidation | PersonalDetailsValidation.PHONE_INVALID @@ -46,6 +53,18 @@ export const ValidateLastName = ( return PersonalDetailsValidation.VALID_FIELD; }; +export const ValidateIdNumber = (id: string): CountryIdNumberValidation => { + const allNumbersValidator = /^[0-9]*$/; + if (!allNumbersValidator.test(id)) { + return PersonalDetailsValidation.ID_HAS_NANS; + } + const formatValidator = /^\d{9}$/; + if (id.length > 0 && !formatValidator.test(id)) { + return PersonalDetailsValidation.ID_INVALID; + } + return PersonalDetailsValidation.VALID_FIELD; +}; + export const ValidatePhone = (phone: string): PhoneValidation => { if (!phone) return PersonalDetailsValidation.REQUIRED_FIELD; diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index e176a5282..1d51e3861 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -30,6 +30,7 @@ export type MinimalDonorDetailsForAppointment = { lastName: string; phoneNumber: string; bloodType: BloodType; + countryIdNumber?: string; }; //https://docs.google.com/document/d/1Y3ovMRJhdHlJEd4rS3FCgxxY3qdpmk2WLaR45nL8IT8 diff --git a/packages/coordinator/src/screens/bookManualDonationScreen/BookManualDonationScreen.tsx b/packages/coordinator/src/screens/bookManualDonationScreen/BookManualDonationScreen.tsx index 95c41ad0c..4ed84dd06 100644 --- a/packages/coordinator/src/screens/bookManualDonationScreen/BookManualDonationScreen.tsx +++ b/packages/coordinator/src/screens/bookManualDonationScreen/BookManualDonationScreen.tsx @@ -21,7 +21,8 @@ export interface BookManualDonationScreenProps { firstName: string, lastName: string, phone: string, - bloodType: BloodType + bloodType: BloodType, + countryIdNumber?: string ) => void; } @@ -38,6 +39,11 @@ export default function BookManualDonationScreen( useState( Validation.PersonalDetailsValidation.VALID_FIELD ); + const [countryIdNumber, setCountryIdNumber] = useState(""); + const [countryIdNumberError, setCountryIdNumberError] = + useState( + Validation.PersonalDetailsValidation.VALID_FIELD + ); const [phone, setPhone] = useState(""); const [phoneError, setPhoneError] = useState( Validation.PersonalDetailsValidation.VALID_FIELD @@ -76,7 +82,7 @@ export default function BookManualDonationScreen( return; } setLoading(true); - props.onSave(firstName, lastName, phone, bloodType); + props.onSave(firstName, lastName, phone, bloodType, countryIdNumber); }; const fullTime = props.donationStartTime.toLocaleDateString( @@ -128,7 +134,19 @@ export default function BookManualDonationScreen( }} errorMessage={LocaleUtils.getValidationErrorTranslation(phoneError)} /> - + { + setCountryIdNumber(nextIdNumber); + setCountryIdNumberError( + Validation.ValidateIdNumber(nextIdNumber) + ); + }} + errorMessage={LocaleUtils.getValidationErrorTranslation( + countryIdNumberError + )} + /> { dispatch( bookManualDonation( @@ -38,6 +39,7 @@ export default function BookManualDonationScreenContainer() { lastName, phoneNumber, bloodType, + countryIdNumber }, () => navigate(-1) ) From eaeaedda240ac9ac93414d7441ff423a65bbb593 Mon Sep 17 00:00:00 2001 From: "yedidya.freundlich" Date: Mon, 14 Mar 2022 12:46:22 +0200 Subject: [PATCH 2/5] style --- packages/common/src/Validation.ts | 2 +- ...BookManualDonationScreen.stories.storyshot | 31 +++++++++++++++++++ .../BookManualDonationScreen.tsx | 4 +-- .../BookManualDonationScreenContainer.tsx | 2 +- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/common/src/Validation.ts b/packages/common/src/Validation.ts index a76a63582..b36230c73 100644 --- a/packages/common/src/Validation.ts +++ b/packages/common/src/Validation.ts @@ -23,7 +23,7 @@ export type LastNameValidation = | PersonalDetailsValidation.FULL_NAME_TOO_LONG; export type CountryIdNumberValidation = - PersonalDetailsValidation.VALID_FIELD + | PersonalDetailsValidation.VALID_FIELD | PersonalDetailsValidation.ID_INVALID | PersonalDetailsValidation.ID_HAS_NANS; diff --git a/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot b/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot index d92f6981c..0b37a4014 100644 --- a/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot +++ b/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot @@ -166,6 +166,37 @@ exports[`Storyshots Screens/Book Manual Donation Screen Default 1`] = ` /> + +
+ +
+ +
+
{ setCountryIdNumber(nextIdNumber); - setCountryIdNumberError( - Validation.ValidateIdNumber(nextIdNumber) - ); + setCountryIdNumberError(Validation.ValidateIdNumber(nextIdNumber)); }} errorMessage={LocaleUtils.getValidationErrorTranslation( countryIdNumberError diff --git a/packages/coordinator/src/screens/bookManualDonationScreen/BookManualDonationScreenContainer.tsx b/packages/coordinator/src/screens/bookManualDonationScreen/BookManualDonationScreenContainer.tsx index 19d24930b..5f0030e00 100644 --- a/packages/coordinator/src/screens/bookManualDonationScreen/BookManualDonationScreenContainer.tsx +++ b/packages/coordinator/src/screens/bookManualDonationScreen/BookManualDonationScreenContainer.tsx @@ -39,7 +39,7 @@ export default function BookManualDonationScreenContainer() { lastName, phoneNumber, bloodType, - countryIdNumber + countryIdNumber, }, () => navigate(-1) ) From 4bf3241089b359c0ebf8a52d88bc69ff48815eca Mon Sep 17 00:00:00 2001 From: "yedidya.freundlich" Date: Sat, 21 May 2022 21:31:51 +0300 Subject: [PATCH 3/5] add id validation and tests --- packages/common/src/Validation.test.ts | 21 +++++++++++++++++++ packages/common/src/Validation.ts | 19 +++++++++++++++++ ...BookManualDonationScreen.stories.storyshot | 2 +- .../BookManualDonationScreen.tsx | 2 +- 4 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/common/src/Validation.test.ts b/packages/common/src/Validation.test.ts index ec48c5421..bec511dae 100644 --- a/packages/common/src/Validation.test.ts +++ b/packages/common/src/Validation.test.ts @@ -3,6 +3,7 @@ import { ValidateFirstName, ValidateLastName, ValidatePhone, + ValidateIdNumber, } from "./Validation"; const VALID_FIRST_NAME = "אלי"; @@ -88,4 +89,24 @@ describe("Validations", function () { const phoneValidation = ValidatePhone(VALID_PHONE); expect(phoneValidation).toEqual(PersonalDetailsValidation.VALID_FIELD); }); + + test("Valid id number returns valid", () => { + const idValidation = ValidateIdNumber("04798562"); + expect(idValidation).toEqual(PersonalDetailsValidation.VALID_FIELD); + }); + + test("Valid id number returns has nans", () => { + const idValidation = ValidateIdNumber("04798e562"); + expect(idValidation).toEqual(PersonalDetailsValidation.ID_HAS_NANS); + }); + + test("Valid id number returns invalid", () => { + const idValidation = ValidateIdNumber("047938562"); + expect(idValidation).toEqual(PersonalDetailsValidation.ID_INVALID); + }); + + test("Valid id number returns invalid", () => { + const idValidation = ValidateIdNumber("04798563"); + expect(idValidation).toEqual(PersonalDetailsValidation.ID_INVALID); + }); }); diff --git a/packages/common/src/Validation.ts b/packages/common/src/Validation.ts index b36230c73..f95ed2c0a 100644 --- a/packages/common/src/Validation.ts +++ b/packages/common/src/Validation.ts @@ -62,6 +62,25 @@ export const ValidateIdNumber = (id: string): CountryIdNumberValidation => { if (id.length > 0 && !formatValidator.test(id)) { return PersonalDetailsValidation.ID_INVALID; } + + let sum = 0; + const digits = id.split(""); + for (let i = 0; i < digits.length - 1; i++) { + const num = Number(digits[i]); + const multiplyer = i % 2 === 0 ? 1 : 2; + + let calc = num * multiplyer; + if (calc > 9) { + calc = 1 + (calc % 10); + } + + sum += calc; + } + + if (Number(digits[length - 1]) !== 10 - (sum % 10)) { + return PersonalDetailsValidation.ID_INVALID; + } + return PersonalDetailsValidation.VALID_FIELD; }; diff --git a/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot b/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot index 0b37a4014..a48ee7a5b 100644 --- a/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot +++ b/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot @@ -176,7 +176,7 @@ exports[`Storyshots Screens/Book Manual Donation Screen Default 1`] = ` className="MuiFormLabel-root-41 MuiInputLabel-root-29 MuiInputLabel-formControl-35 MuiInputLabel-animated-38" data-shrink={false} > - תעודת זהות + מספר תעודת זהות
{ setCountryIdNumber(nextIdNumber); From 7c9d667904175a64cf075ec653507f694feb99f6 Mon Sep 17 00:00:00 2001 From: "yedidya.freundlich" Date: Sat, 21 May 2022 21:42:35 +0300 Subject: [PATCH 4/5] Revert "add id validation and tests" This reverts commit 4bf3241089b359c0ebf8a52d88bc69ff48815eca. --- packages/common/src/Validation.test.ts | 21 ------------------- packages/common/src/Validation.ts | 19 ----------------- ...BookManualDonationScreen.stories.storyshot | 2 +- .../BookManualDonationScreen.tsx | 2 +- 4 files changed, 2 insertions(+), 42 deletions(-) diff --git a/packages/common/src/Validation.test.ts b/packages/common/src/Validation.test.ts index bec511dae..ec48c5421 100644 --- a/packages/common/src/Validation.test.ts +++ b/packages/common/src/Validation.test.ts @@ -3,7 +3,6 @@ import { ValidateFirstName, ValidateLastName, ValidatePhone, - ValidateIdNumber, } from "./Validation"; const VALID_FIRST_NAME = "אלי"; @@ -89,24 +88,4 @@ describe("Validations", function () { const phoneValidation = ValidatePhone(VALID_PHONE); expect(phoneValidation).toEqual(PersonalDetailsValidation.VALID_FIELD); }); - - test("Valid id number returns valid", () => { - const idValidation = ValidateIdNumber("04798562"); - expect(idValidation).toEqual(PersonalDetailsValidation.VALID_FIELD); - }); - - test("Valid id number returns has nans", () => { - const idValidation = ValidateIdNumber("04798e562"); - expect(idValidation).toEqual(PersonalDetailsValidation.ID_HAS_NANS); - }); - - test("Valid id number returns invalid", () => { - const idValidation = ValidateIdNumber("047938562"); - expect(idValidation).toEqual(PersonalDetailsValidation.ID_INVALID); - }); - - test("Valid id number returns invalid", () => { - const idValidation = ValidateIdNumber("04798563"); - expect(idValidation).toEqual(PersonalDetailsValidation.ID_INVALID); - }); }); diff --git a/packages/common/src/Validation.ts b/packages/common/src/Validation.ts index f95ed2c0a..b36230c73 100644 --- a/packages/common/src/Validation.ts +++ b/packages/common/src/Validation.ts @@ -62,25 +62,6 @@ export const ValidateIdNumber = (id: string): CountryIdNumberValidation => { if (id.length > 0 && !formatValidator.test(id)) { return PersonalDetailsValidation.ID_INVALID; } - - let sum = 0; - const digits = id.split(""); - for (let i = 0; i < digits.length - 1; i++) { - const num = Number(digits[i]); - const multiplyer = i % 2 === 0 ? 1 : 2; - - let calc = num * multiplyer; - if (calc > 9) { - calc = 1 + (calc % 10); - } - - sum += calc; - } - - if (Number(digits[length - 1]) !== 10 - (sum % 10)) { - return PersonalDetailsValidation.ID_INVALID; - } - return PersonalDetailsValidation.VALID_FIELD; }; diff --git a/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot b/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot index a48ee7a5b..0b37a4014 100644 --- a/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot +++ b/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot @@ -176,7 +176,7 @@ exports[`Storyshots Screens/Book Manual Donation Screen Default 1`] = ` className="MuiFormLabel-root-41 MuiInputLabel-root-29 MuiInputLabel-formControl-35 MuiInputLabel-animated-38" data-shrink={false} > - מספר תעודת זהות + תעודת זהות
{ setCountryIdNumber(nextIdNumber); From fb8953cbabd3f8ecb3ff10b6351154090414ddb5 Mon Sep 17 00:00:00 2001 From: evbambly <45696895+evbambly@users.noreply.github.com> Date: Sat, 28 May 2022 14:16:29 +0300 Subject: [PATCH 5/5] Storybook update --- ...BookManualDonationScreen.stories.storyshot | 61 +++++++++---------- .../ReportsScreen.stories.storyshot | 36 +++++------ 2 files changed, 48 insertions(+), 49 deletions(-) diff --git a/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot b/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot index 1dbfb13c6..c9e564420 100644 --- a/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot +++ b/packages/coordinator/src/__test__/src/screens/bookManualDonationScreen/__snapshots__/BookManualDonationScreen.stories.storyshot @@ -323,7 +323,7 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-4:focus::-ms-input-p animation-name: mui-auto-fill; } -.emotion-13 { +.emotion-17 { display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; @@ -373,23 +373,23 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-4:focus::-ms-input-p box-shadow: none; } -.emotion-13::-moz-focus-inner { +.emotion-17::-moz-focus-inner { border-style: none; } -.emotion-13.Mui-disabled { +.emotion-17.Mui-disabled { pointer-events: none; cursor: default; } @media print { - .emotion-13 { + .emotion-17 { -webkit-print-color-adjust: exact; color-adjust: exact; } } -.emotion-13:hover { +.emotion-17:hover { -webkit-text-decoration: none; text-decoration: none; background-color: rgb(53, 122, 56); @@ -397,42 +397,42 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-4:focus::-ms-input-p } @media (hover: none) { - .emotion-13:hover { + .emotion-17:hover { background-color: #4caf51; } } -.emotion-13:active { +.emotion-17:active { box-shadow: 0px 5px 5px -3px rgba(0,0,0,0.2),0px 8px 10px 1px rgba(0,0,0,0.14),0px 3px 14px 2px rgba(0,0,0,0.12); } -.emotion-13.Mui-focusVisible { +.emotion-17.Mui-focusVisible { box-shadow: 0px 3px 5px -1px rgba(0,0,0,0.2),0px 6px 10px 0px rgba(0,0,0,0.14),0px 1px 18px 0px rgba(0,0,0,0.12); } -.emotion-13.Mui-disabled { +.emotion-17.Mui-disabled { color: #7E7E7E; box-shadow: none; background-color: #dadee0; } -.emotion-13:hover { +.emotion-17:hover { box-shadow: none; } -.emotion-13.Mui-focusVisible { +.emotion-17.Mui-focusVisible { box-shadow: none; } -.emotion-13:active { +.emotion-17:active { box-shadow: none; } -.emotion-13.Mui-disabled { +.emotion-17.Mui-disabled { box-shadow: none; } -.emotion-14 { +.emotion-18 { display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; @@ -481,23 +481,23 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-4:focus::-ms-input-p box-shadow: none; } -.emotion-14::-moz-focus-inner { +.emotion-18::-moz-focus-inner { border-style: none; } -.emotion-14.Mui-disabled { +.emotion-18.Mui-disabled { pointer-events: none; cursor: default; } @media print { - .emotion-14 { + .emotion-18 { -webkit-print-color-adjust: exact; color-adjust: exact; } } -.emotion-14:hover { +.emotion-18:hover { -webkit-text-decoration: none; text-decoration: none; background-color: rgba(76, 175, 81, 0.04); @@ -505,29 +505,29 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-4:focus::-ms-input-p } @media (hover: none) { - .emotion-14:hover { + .emotion-18:hover { background-color: transparent; } } -.emotion-14.Mui-disabled { +.emotion-18.Mui-disabled { color: #7E7E7E; border: 1px solid #dadee0; } -.emotion-14:hover { +.emotion-18:hover { box-shadow: none; } -.emotion-14.Mui-focusVisible { +.emotion-18.Mui-focusVisible { box-shadow: none; } -.emotion-14:active { +.emotion-18:active { box-shadow: none; } -.emotion-14.Mui-disabled { +.emotion-18.Mui-disabled { box-shadow: none; } @@ -692,24 +692,23 @@ label[data-shrink=false]+.MuiInputBase-formControl .emotion-4:focus::-ms-input-p