From 9577f810bc1f7c3a4f29e7bc5140daf10d95c5b4 Mon Sep 17 00:00:00 2001 From: Max <133934232+Kleostro@users.noreply.github.com> Date: Wed, 1 May 2024 02:09:09 +0300 Subject: [PATCH] feat: add new validators for RegistrationForm --- src/app/App/model/AppModel.ts | 2 +- .../InputField/view/InputFieldView.ts | 3 +- .../model/InputFieldValidatorModel.ts | 36 +++ src/pages/MainPage/model/MainPageModel.ts | 4 + src/shared/constants/enums.ts | 205 +++++++++++++++++- src/shared/img/svg/calendar.svg | 3 + src/shared/types/interfaces.ts | 11 +- 7 files changed, 259 insertions(+), 5 deletions(-) create mode 100644 src/shared/img/svg/calendar.svg diff --git a/src/app/App/model/AppModel.ts b/src/app/App/model/AppModel.ts index c10af0e7..d7664952 100644 --- a/src/app/App/model/AppModel.ts +++ b/src/app/App/model/AppModel.ts @@ -22,7 +22,7 @@ class AppModel { const root = this.getHTML(); const loginPage = new LoginPageModel(root, this.router); const mainPage = new MainPageModel(root); - const registrationPage = new RegistrationPageModel(root); + const registrationPage = new RegistrationPageModel(root, this.router); const notFoundPage = new NotFoundPageModel(root); const pages: Map = new Map( Object.entries({ diff --git a/src/entities/InputField/view/InputFieldView.ts b/src/entities/InputField/view/InputFieldView.ts index 069de0c4..f31df1b9 100644 --- a/src/entities/InputField/view/InputFieldView.ts +++ b/src/entities/InputField/view/InputFieldView.ts @@ -49,10 +49,11 @@ class InputFieldView { } private createInput(inputParams: InputParams): InputModel { - const { autocomplete, id, placeholder, type } = inputParams; + const { autocomplete, id, lang, placeholder, type } = inputParams; this.input = new InputModel({ autocomplete, id, + lang: lang || '', placeholder: placeholder || '', type, }); diff --git a/src/features/InputFieldValidator/model/InputFieldValidatorModel.ts b/src/features/InputFieldValidator/model/InputFieldValidatorModel.ts index 0ab94d8e..c6041e0e 100644 --- a/src/features/InputFieldValidator/model/InputFieldValidatorModel.ts +++ b/src/features/InputFieldValidator/model/InputFieldValidatorModel.ts @@ -10,6 +10,18 @@ class InputFieldValidatorModel { this.isValid = isValid; } + private checkMaxAge(value: string): boolean | string { + const today = new Date(); + const birthDate = new Date(value); + const age = today.getFullYear() - birthDate.getFullYear(); + if (this.validParams.validBirthday && age > this.validParams.validBirthday.maxAge) { + const errorMessage = `You must be at most ${this.validParams.validBirthday.maxAge} years old`; + return errorMessage; + } + + return true; + } + private checkMaxLength(value: string): boolean | string { if (this.validParams.maxLength && value.length > this.validParams.maxLength) { const errorMessage = `Max length should not exceed ${this.validParams.maxLength}`; @@ -19,6 +31,18 @@ class InputFieldValidatorModel { return true; } + private checkMinAge(value: string): boolean | string { + const today = new Date(); + const birthDate = new Date(value); + const age = today.getFullYear() - birthDate.getFullYear(); + if (this.validParams.validBirthday && age < this.validParams.validBirthday.minAge) { + const errorMessage = `You must be at least ${this.validParams.validBirthday.minAge} years old`; + return errorMessage; + } + + return true; + } + private checkMinLength(value: string): boolean | string { if (this.validParams.minLength && value.length < this.validParams.minLength) { const errorMessage = `Min length should be at least ${this.validParams.minLength}`; @@ -55,6 +79,15 @@ class InputFieldValidatorModel { return true; } + private checkValidAge(value: string): boolean | string { + if (this.validParams.validBirthday && !this.validParams.validBirthday.pattern.test(value)) { + const errorMessage = this.validParams.validBirthday.message; + return errorMessage; + } + + return true; + } + private checkValidMail(value: string): boolean | string { if (this.validParams.validMail && !this.validParams.validMail.pattern.test(value)) { const errorMessage = this.validParams.validMail.message; @@ -82,6 +115,9 @@ class InputFieldValidatorModel { this.checkMaxLength(value), this.checkRequiredSymbols(value), this.checkValidMail(value), + this.checkValidAge(value), + this.checkMinAge(value), + this.checkMaxAge(value), ]; const errorMessages: string[] = []; diff --git a/src/pages/MainPage/model/MainPageModel.ts b/src/pages/MainPage/model/MainPageModel.ts index 0f07f18d..a8019df3 100644 --- a/src/pages/MainPage/model/MainPageModel.ts +++ b/src/pages/MainPage/model/MainPageModel.ts @@ -12,6 +12,10 @@ class MainPageModel implements PageInterface { constructor(parent: HTMLDivElement) { this.view = new MainPageView(parent); + this.init(); + } + + private init(): void { this.subscribeToEventMediator(); } diff --git a/src/shared/constants/enums.ts b/src/shared/constants/enums.ts index 12148274..b6f017d4 100644 --- a/src/shared/constants/enums.ts +++ b/src/shared/constants/enums.ts @@ -192,5 +192,208 @@ export const PAGE_LINK_TEXT = { } as const; export const PAGE_DESCRIPTION = { - LOGIN: 'Enter your email and password to register.', + LOGIN: 'Enter your email and password to login.', + REGISTRATION: 'Enter your email and password to register.', } as const; + +export const REGISTRATION_FORM_EMAIL_FIELD_PARAMS = { + inputParams: { + autocomplete: 'off', + id: 'email', + placeholder: 'user@example.com', + type: 'text', + }, + labelParams: { + for: 'email', + text: '', + }, +} as const; + +export const REGISTRATION_FORM_PASSWORD_FIELD_PARAMS = { + inputParams: { + autocomplete: 'off', + id: 'password', + placeholder: '***********', + type: 'password', + }, + labelParams: { + for: 'password', + text: '', + }, +} as const; + +export const REGISTRATION_FORM_FIRST_NAME_FIELD_PARAMS = { + inputParams: { + autocomplete: 'off', + id: 'firstName', + placeholder: 'John', + type: 'text', + }, + labelParams: { + for: 'firstName', + text: '', + }, +} as const; + +export const REGISTRATION_FORM_LAST_NAME_FIELD_PARAMS = { + inputParams: { + autocomplete: 'off', + id: 'lastName', + placeholder: 'Doe', + type: 'text', + }, + labelParams: { + for: 'lastName', + text: '', + }, +} as const; + +export const REGISTRATION_FORM_BIRTHDAY_FIELD_PARAMS = { + inputParams: { + autocomplete: 'off', + id: 'birthday', + lang: 'en', + placeholder: '01.01.2000', + type: 'date', + }, + labelParams: { + for: 'birthday', + text: '', + }, +} as const; + +export const REGISTRATION_FORM_STREET_FIELD_PARAMS = { + inputParams: { + autocomplete: 'off', + id: 'street', + placeholder: 'Street', + type: 'text', + }, + labelParams: { + for: 'street', + text: '', + }, +}; + +export const REGISTRATION_FORM_CITY_FIELD_PARAMS = { + inputParams: { + autocomplete: 'off', + id: 'city', + placeholder: 'City', + type: 'text', + }, + labelParams: { + for: 'city', + text: '', + }, +}; + +export const REGISTRATION_FORM_INPUT_FIELD_PARAMS = [ + REGISTRATION_FORM_EMAIL_FIELD_PARAMS, + REGISTRATION_FORM_PASSWORD_FIELD_PARAMS, + REGISTRATION_FORM_FIRST_NAME_FIELD_PARAMS, + REGISTRATION_FORM_LAST_NAME_FIELD_PARAMS, + REGISTRATION_FORM_BIRTHDAY_FIELD_PARAMS, + REGISTRATION_FORM_STREET_FIELD_PARAMS, + REGISTRATION_FORM_CITY_FIELD_PARAMS, +]; + +const REGISTRATION_FORM_EMAIL_FIELD_VALIDATE_PARAMS = { + key: 'email', + notWhitespace: { + message: 'Email must not contain whitespaces', + pattern: /^\S+$/, + }, + required: true, + validMail: { + message: 'Enter correct email (user@example.com)', + pattern: /^([a-z0-9_-]+\.)*[a-z0-9_-]+@[a-z0-9_-]+(\.[a-z0-9_-]+)*\.[a-z]{2,6}$/, + }, +} as const; + +const REGISTRATION_FORM_PASSWORD_FIELD_VALIDATE_PARAMS = { + key: 'password', + minLength: 8, + notWhitespace: { + message: 'Password must not contain whitespaces', + pattern: /^\S+$/, + }, + required: true, + requiredSymbols: { + message: 'Password must contain English letters, at least 1 letter in upper and lower case and at least 1 number', + pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+/, + }, +} as const; + +const REGISTRATION_FORM_FIRST_NAME_FIELD_VALIDATE_PARAMS = { + key: 'firstName', + minLength: 1, + notSpecialSymbols: { + message: 'First name must contain only letters', + pattern: /^[a-zA-Z]*$/, + }, + notWhitespace: { + message: 'First name must not contain whitespaces', + pattern: /^\S+$/, + }, + required: true, +} as const; + +const REGISTRATION_FORM_LAST_NAME_FIELD_VALIDATE_PARAMS = { + key: 'lastName', + minLength: 1, + notSpecialSymbols: { + message: 'Last name must contain only letters', + pattern: /^[a-zA-Z]*$/, + }, + notWhitespace: { + message: 'Last name must not contain whitespaces', + pattern: /^\S+$/, + }, + required: true, +} as const; + +const REGISTRATION_FORM_BIRTHDAY_FIELD_VALIDATE_PARAMS = { + key: 'birthday', + required: true, + validBirthday: { + maxAge: 120, + message: 'Enter correct birthday (01.01.2000)', + minAge: 18, + pattern: /^\d{4}-\d{2}-\d{2}$/, + }, +} as const; + +export const REGISTRATION_FORM_STREET_FIELD_VALIDATE_PARAMS = { + key: 'street', + minLength: 1, + notWhitespace: { + message: 'Street must not contain whitespaces', + pattern: /^\S.*\S$/, + }, + required: true, +}; + +export const REGISTRATION_FORM_CITY_FIELD_VALIDATE_PARAMS = { + key: 'city', + minLength: 1, + notSpecialSymbols: { + message: 'City must contain only letters', + pattern: /^[a-zA-Z]*$/, + }, + notWhitespace: { + message: 'City must not contain whitespaces', + pattern: /^\S.*\S$/, + }, + required: true, +}; + +export const REGISTRATION_FORM_INPUT_FIELD_VALIDATION_PARAMS = [ + REGISTRATION_FORM_EMAIL_FIELD_VALIDATE_PARAMS, + REGISTRATION_FORM_PASSWORD_FIELD_VALIDATE_PARAMS, + REGISTRATION_FORM_FIRST_NAME_FIELD_VALIDATE_PARAMS, + REGISTRATION_FORM_LAST_NAME_FIELD_VALIDATE_PARAMS, + REGISTRATION_FORM_BIRTHDAY_FIELD_VALIDATE_PARAMS, + REGISTRATION_FORM_STREET_FIELD_VALIDATE_PARAMS, + REGISTRATION_FORM_CITY_FIELD_VALIDATE_PARAMS, +]; diff --git a/src/shared/img/svg/calendar.svg b/src/shared/img/svg/calendar.svg new file mode 100644 index 00000000..c7a34389 --- /dev/null +++ b/src/shared/img/svg/calendar.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/shared/types/interfaces.ts b/src/shared/types/interfaces.ts index 73b7a15f..364dc424 100644 --- a/src/shared/types/interfaces.ts +++ b/src/shared/types/interfaces.ts @@ -12,10 +12,11 @@ export interface PageInterface { } export interface InputParams { - autocomplete: 'off' | 'on'; + autocomplete: string; id: string; + lang?: string; placeholder: null | string; - type: 'color' | 'date' | 'email' | 'number' | 'password' | 'range' | 'text'; + type: string; } export interface LabelParams { @@ -45,6 +46,12 @@ export interface InputFieldValidatorParams { message: string; pattern: RegExp; } | null; + validBirthday?: { + maxAge: number; + message: string; + minAge: number; + pattern: RegExp; + } | null; validMail?: { message: string; pattern: RegExp;