diff --git a/src/entities/Address/model/AddressModel.ts b/src/entities/Address/model/AddressModel.ts index 0a46ac44..6391c0a5 100644 --- a/src/entities/Address/model/AddressModel.ts +++ b/src/entities/Address/model/AddressModel.ts @@ -3,6 +3,7 @@ import type { Address, PersonalData } from '@/shared/types/user.ts'; import CountryChoiceModel from '@/features/CountryChoice/model/CountryChoiceModel.ts'; import getStore from '@/shared/Store/Store.ts'; import { ADDRESS_TYPE, type AddressOptions, type AddressType } from '@/shared/types/address.ts'; +import formattedText from '@/shared/utils/formattedText.ts'; import AddressView from '../view/AddressView.ts'; @@ -25,7 +26,7 @@ class AddressModel { public getAddressData(personalData: PersonalData): Address { const store = getStore().getState(); const addressData: Address = { - city: this.view.getCityField().getView().getValue(), + city: formattedText(this.view.getCityField().getView().getValue()), country: this.addressType === ADDRESS_TYPE.BILLING ? store.billingCountry : store.shippingCountry, email: personalData.email, firstName: personalData.firstName, @@ -33,7 +34,7 @@ class AddressModel { lastName: personalData.lastName, postalCode: this.view.getPostalCodeField().getView().getValue(), state: '', - streetName: this.view.getStreetField().getView().getValue(), + streetName: formattedText(this.view.getStreetField().getView().getValue()), streetNumber: '', }; return addressData; diff --git a/src/entities/Address/view/AddressView.ts b/src/entities/Address/view/AddressView.ts index 85c1e353..8a65d042 100644 --- a/src/entities/Address/view/AddressView.ts +++ b/src/entities/Address/view/AddressView.ts @@ -43,8 +43,10 @@ class AddressView { private appendInputFields(): void { this.inputFields.forEach((inputField) => { const inputFieldElement = inputField.getView().getHTML(); + const inputHTML = inputField.getView().getInput().getHTML(); if (inputFieldElement instanceof HTMLLabelElement) { inputFieldElement.classList.add(styles.label); + inputHTML.classList.add(styles.input); this.address.append(inputFieldElement); } else if (inputFieldElement instanceof InputModel) { this.address.append(inputFieldElement.getHTML()); @@ -156,7 +158,13 @@ class AddressView { this.appendInputFields(); if (this.options.setDefault) { - this.address.append(this.createAddressByDefaultCheckbox(FORM_TEXT.DEFAULT_ADDRESS)); + this.address.append( + this.createAddressByDefaultCheckbox( + this.addressType === ADDRESS_TYPE.SHIPPING + ? FORM_TEXT.DEFAULT_SHIPPING_ADDRESS + : FORM_TEXT.DEFAULT_BILLING_ADDRESS, + ), + ); } if (this.options.setAsBilling) { this.address.append(this.createAddressAsBillingCheckbox(FORM_TEXT.SINGLE_ADDRESS)); diff --git a/src/entities/Address/view/addressView.module.scss b/src/entities/Address/view/addressView.module.scss index 0a5ec29f..198bf550 100644 --- a/src/entities/Address/view/addressView.module.scss +++ b/src/entities/Address/view/addressView.module.scss @@ -111,6 +111,7 @@ .checkboxText { font: var(--regular-font); letter-spacing: 1px; + text-align: end; color: var(--noble-gray-800); transition: color 0.2s; } @@ -124,3 +125,54 @@ color: var(--noble-gray-800); gap: calc(var(--extra-small-offset) / 2); } + +.input { + border: 1px solid var(--noble-gray-200); + border-radius: var(--small-br); + padding: calc(var(--extra-small-offset) / 2) var(--extra-small-offset); + font: var(--regular-font); + letter-spacing: 1px; + color: var(--noble-gray-800); + transition: border 0.2s; + cursor: text; + + &::placeholder { + color: var(--noble-gray-600); + } + + &:focus { + border: 1px solid var(--steam-green-800); + } + + @media (hover: hover) { + &:hover { + border: 1px solid var(--steam-green-800); + } + } + + &[type='date'] { + -webkit-appearance: none; + appearance: none; + padding-right: 0; + } + + &[type='date']::-webkit-calendar-picker-indicator { + background-image: url('../../../shared/img/svg/calendar.svg'); + background-position: -3px 0; + cursor: pointer; + } + + &[type='date']::-webkit-inner-spin-button, + &[type='date']::-webkit-outer-spin-button { + display: none; + } + + &::-webkit-datetime-edit-day-field:focus, + &::-webkit-datetime-edit-month-field:focus, + &::-webkit-datetime-edit-year-field:focus { + outline: none; + border-radius: var(--small-br); + color: var(--steam-green-800); + background-color: var(--noble-gray-200); + } +} diff --git a/src/features/CountryChoice/model/CountryChoiceModel.ts b/src/features/CountryChoice/model/CountryChoiceModel.ts index e93baf62..48c82e5f 100644 --- a/src/features/CountryChoice/model/CountryChoiceModel.ts +++ b/src/features/CountryChoice/model/CountryChoiceModel.ts @@ -7,6 +7,7 @@ import observeStore, { } from '@/shared/Store/observer.ts'; import COUNTRIES_LIST from '@/shared/constants/countriesList.ts'; import { BILLING_ADDRESS_COUNTRY } from '@/shared/constants/forms/register/fieldParams.ts'; +import formattedText from '@/shared/utils/formattedText.ts'; import getCountryIndex from '@/shared/utils/getCountryIndex.ts'; import CountryChoiceView from '../view/CountryChoiceView.ts'; @@ -60,7 +61,7 @@ class CountryChoiceModel { private setCountryToStore(element: HTMLDivElement | HTMLInputElement, key: string): boolean { const currentCountryIndex = getCountryIndex( - element instanceof HTMLDivElement ? element.textContent || '' : element.value, + element instanceof HTMLDivElement ? formattedText(element.textContent ?? '') || '' : formattedText(element.value), ); const action = key === BILLING_ADDRESS_COUNTRY.inputParams.id ? setBillingCountry : setShippingCountry; diff --git a/src/features/CountryChoice/view/countryChoiceView.module.scss b/src/features/CountryChoice/view/countryChoiceView.module.scss index 3e71d321..cbf2392c 100644 --- a/src/features/CountryChoice/view/countryChoiceView.module.scss +++ b/src/features/CountryChoice/view/countryChoiceView.module.scss @@ -3,6 +3,7 @@ z-index: 5; grid-column: 1; grid-row: 4; + transform: translateY(-127%); transition: opacity 0.2s, visibility 0.2s; @@ -17,7 +18,7 @@ padding: calc(var(--extra-small-offset) / 4) calc(var(--extra-small-offset) / 2); font: var(--regular-font); letter-spacing: 1px; - text-align: end; + text-align: start; color: var(--noble-gray-800); transition: color 0.2s, diff --git a/src/pages/LoginPage/view/loginPageView.module.scss b/src/pages/LoginPage/view/loginPageView.module.scss index 0d92bfeb..56336283 100644 --- a/src/pages/LoginPage/view/loginPageView.module.scss +++ b/src/pages/LoginPage/view/loginPageView.module.scss @@ -120,6 +120,7 @@ grid-column: 2 span; grid-row: 4; font: var(--regular-font); + letter-spacing: 1px; text-align: center; color: var(--steam-green-800); gap: calc(var(--extra-small-offset) / 4); diff --git a/src/pages/RegistrationPage/view/registrationPageView.module.scss b/src/pages/RegistrationPage/view/registrationPageView.module.scss index 014f647c..e61aaac4 100644 --- a/src/pages/RegistrationPage/view/registrationPageView.module.scss +++ b/src/pages/RegistrationPage/view/registrationPageView.module.scss @@ -125,6 +125,7 @@ grid-column: 2 span; grid-row: 4; font: var(--regular-font); + letter-spacing: 1px; text-align: center; color: var(--steam-green-800); gap: calc(var(--extra-small-offset) / 4); diff --git a/src/shared/constants/forms.ts b/src/shared/constants/forms.ts index d0342ecf..44acd75a 100644 --- a/src/shared/constants/forms.ts +++ b/src/shared/constants/forms.ts @@ -11,8 +11,9 @@ export const INPUT_TYPE = { } as const; export const FORM_TEXT = { - DEFAULT_ADDRESS: 'Use as default address', - SINGLE_ADDRESS: 'Use as billing address', + DEFAULT_BILLING_ADDRESS: 'Use as Default for Billing', + DEFAULT_SHIPPING_ADDRESS: 'Use as Default for Shipping', + SINGLE_ADDRESS: 'Use Shipping Address for Billing', }; export const USER_COUNTRY_ADDRESS = { diff --git a/src/shared/constants/forms/register/fieldParams.ts b/src/shared/constants/forms/register/fieldParams.ts index 489ba1eb..429fa7c1 100644 --- a/src/shared/constants/forms/register/fieldParams.ts +++ b/src/shared/constants/forms/register/fieldParams.ts @@ -7,7 +7,7 @@ export const EMAIL = { }, labelParams: { for: 'registration_email', - text: 'Email *', + text: 'Email', }, } as const; @@ -20,7 +20,7 @@ export const PASSWORD = { }, labelParams: { for: 'registration_password', - text: 'Password *', + text: 'Password', }, } as const; @@ -33,7 +33,7 @@ export const FIRST_NAME = { }, labelParams: { for: 'firstName', - text: 'First name *', + text: 'First name', }, } as const; @@ -46,7 +46,7 @@ export const LAST_NAME = { }, labelParams: { for: 'lastName', - text: 'Last name *', + text: 'Last name', }, } as const; @@ -60,7 +60,7 @@ export const BIRTHDAY = { }, labelParams: { for: 'birthDate', - text: 'Date of Birth *', + text: 'Date of Birth', }, } as const; @@ -73,7 +73,7 @@ export const SHIPPING_ADDRESS_STREET = { }, labelParams: { for: 'address', - text: 'Address *', + text: 'Address', }, } as const; @@ -86,7 +86,7 @@ export const SHIPPING_ADDRESS_CITY = { }, labelParams: { for: 'city', - text: 'City *', + text: 'City', }, } as const; @@ -99,7 +99,7 @@ export const SHIPPING_ADDRESS_COUNTRY = { }, labelParams: { for: 'shippingCountry', - text: 'Country *', + text: 'Country', }, } as const; @@ -112,7 +112,7 @@ export const SHIPPING_ADDRESS_POSTAL_CODE = { }, labelParams: { for: 'postalCode', - text: 'Postal code *', + text: 'Postal code', }, } as const; @@ -125,7 +125,7 @@ export const BILLING_ADDRESS_STREET = { }, labelParams: { for: 'billing_address', - text: 'Address *', + text: 'Address', }, } as const; @@ -138,7 +138,7 @@ export const BILLING_ADDRESS_CITY = { }, labelParams: { for: 'billing_city', - text: 'City *', + text: 'City', }, } as const; @@ -151,7 +151,7 @@ export const BILLING_ADDRESS_COUNTRY = { }, labelParams: { for: 'billing_country', - text: 'Country *', + text: 'Country', }, } as const; @@ -164,7 +164,7 @@ export const BILLING_ADDRESS_POSTAL_CODE = { }, labelParams: { for: 'billing_postalCode', - text: 'Postal code *', + text: 'Postal code', }, } as const; diff --git a/src/shared/constants/forms/register/validationParams.ts b/src/shared/constants/forms/register/validationParams.ts index 948e18c5..5b714bfb 100644 --- a/src/shared/constants/forms/register/validationParams.ts +++ b/src/shared/constants/forms/register/validationParams.ts @@ -39,7 +39,7 @@ export const FIRST_NAME_VALIDATE = { en: 'First name must contain only letters', ru: 'Имя должно содержать только буквы', }, - pattern: /^[a-zA-Z]*$/, + pattern: /^[a-zA-Zа-яА-я\s]*$/, }, notWhitespace: { messages: { @@ -59,7 +59,7 @@ export const LAST_NAME_VALIDATE = { en: 'Last name must contain only letters', ru: 'Фамилия должна содержать только буквы', }, - pattern: /^[a-zA-Z]*$/, + pattern: /^[a-zA-Zа-яА-я\s]*$/, }, notWhitespace: { messages: { @@ -99,7 +99,7 @@ export const SHIPPING_ADDRESS_CITY_VALIDATE = { en: 'City must contain only letters', ru: 'Город должен содержать только буквы', }, - pattern: /^[a-zA-Z]*$/, + pattern: /^[a-zA-Zа-яА-я\s]*$/, }, required: true, @@ -131,7 +131,7 @@ export const BILLING_ADDRESS_CITY_VALIDATE = { en: 'City must contain only letters', ru: 'Город должен содержать только буквы', }, - pattern: /^[a-zA-Z]*$/, + pattern: /^[a-zA-Zа-яА-я\s]*$/, }, required: true, }; diff --git a/src/shared/utils/formattedText.ts b/src/shared/utils/formattedText.ts new file mode 100644 index 00000000..651faaed --- /dev/null +++ b/src/shared/utils/formattedText.ts @@ -0,0 +1,8 @@ +const formattedText = (text: string): string => + text + .trim() + .split(' ') + .map((word) => (word[0] ? word[0].toUpperCase() + word.slice(1).toLowerCase() : '')) + .join(' '); + +export default formattedText; diff --git a/src/widgets/RegistrationForm/model/RegistrationFormModel.ts b/src/widgets/RegistrationForm/model/RegistrationFormModel.ts index 10886f94..94d3b44e 100644 --- a/src/widgets/RegistrationForm/model/RegistrationFormModel.ts +++ b/src/widgets/RegistrationForm/model/RegistrationFormModel.ts @@ -14,6 +14,7 @@ import { INPUT_TYPE, PASSWORD_TEXT } from '@/shared/constants/forms.ts'; import { MESSAGE_STATUS, SERVER_MESSAGE } from '@/shared/constants/messages.ts'; import { SIZES } from '@/shared/constants/sizes.ts'; import { ADDRESS_TYPE } from '@/shared/types/address.ts'; +import formattedText from '@/shared/utils/formattedText.ts'; import RegistrationFormView from '../view/RegistrationFormView.ts'; @@ -85,9 +86,9 @@ class RegisterFormModel { defaultBillingAddressId: null, defaultShippingAddressId: null, email: this.view.getEmailField().getView().getValue(), - firstName: this.view.getFirstNameField().getView().getValue(), + firstName: formattedText(this.view.getFirstNameField().getView().getValue()), id: '', - lastName: this.view.getLastNameField().getView().getValue(), + lastName: formattedText(this.view.getLastNameField().getView().getValue()), locale: '', password: this.view.getPasswordField().getView().getValue(), version: 0, @@ -100,8 +101,8 @@ class RegisterFormModel { private getPersonalData(): PersonalData { return { email: this.view.getEmailField().getView().getValue(), - firstName: this.view.getFirstNameField().getView().getValue(), - lastName: this.view.getLastNameField().getView().getValue(), + firstName: formattedText(this.view.getFirstNameField().getView().getValue()), + lastName: formattedText(this.view.getLastNameField().getView().getValue()), }; } @@ -243,7 +244,6 @@ class RegisterFormModel { private switchSubmitFormButtonAccess(): boolean { if (this.inputFields.every((inputField) => inputField.getIsValid())) { this.view.getSubmitFormButton().setEnabled(); - this.view.getSubmitFormButton().getHTML().focus(); } else { this.view.getSubmitFormButton().setDisabled(); } @@ -256,8 +256,8 @@ class RegisterFormModel { if (currentUserData) { currentUserData = await getCustomerModel().editCustomer( [ - CustomerModel.actionEditFirstName(this.view.getFirstNameField().getView().getValue()), - CustomerModel.actionEditLastName(this.view.getLastNameField().getView().getValue()), + CustomerModel.actionEditFirstName(formattedText(this.view.getFirstNameField().getView().getValue())), + CustomerModel.actionEditLastName(formattedText(this.view.getLastNameField().getView().getValue())), CustomerModel.actionEditDateOfBirth(this.view.getDateOfBirthField().getView().getValue()), ], currentUserData, diff --git a/src/widgets/RegistrationForm/view/RegistrationFormView.ts b/src/widgets/RegistrationForm/view/RegistrationFormView.ts index 9c8e91a6..43296036 100644 --- a/src/widgets/RegistrationForm/view/RegistrationFormView.ts +++ b/src/widgets/RegistrationForm/view/RegistrationFormView.ts @@ -161,8 +161,10 @@ class RegistrationFormView { inputFields.forEach((inputField) => { const inputFieldElement = inputField.getView().getHTML(); + const inputHTML = inputField.getView().getInput().getHTML(); if (inputFieldElement instanceof HTMLLabelElement) { inputFieldElement.classList.add(styles.label); + inputHTML.classList.add(styles.input); wrapperElement.append(inputFieldElement); } else if (inputFieldElement instanceof InputModel) { wrapperElement.append(inputFieldElement.getHTML()); diff --git a/src/widgets/RegistrationForm/view/registrationForm.module.scss b/src/widgets/RegistrationForm/view/registrationForm.module.scss index 47c086d3..f92b5577 100644 --- a/src/widgets/RegistrationForm/view/registrationForm.module.scss +++ b/src/widgets/RegistrationForm/view/registrationForm.module.scss @@ -17,98 +17,6 @@ gap: calc(var(--extra-small-offset) / 2); } - .showPasswordElement { - position: absolute; - right: 0; - top: 34px; - border-radius: var(--small-br); - padding: calc(var(--extra-small-offset) / 8); - width: 24px; - height: 24px; - background-color: transparent; - transform: translate(-12%, 0); - - svg { - width: 20px; - height: 20px; - stroke: var(--noble-gray-600); - transition: stroke 0.2s; - } - - &:focus { - background-color: var(--noble-gray-200); - - svg { - stroke: var(--steam-green-800); - } - } - - @media (hover: hover) { - &:hover { - background-color: var(--noble-gray-200); - - svg { - stroke: var(--steam-green-800); - } - } - } - - @media (max-width: 768px) { - top: 24px; - } - } - - input { - border: 1px solid var(--noble-gray-200); - border-radius: var(--small-br); - padding: calc(var(--extra-small-offset) / 2) var(--extra-small-offset); - font: var(--regular-font); - letter-spacing: 1px; - color: var(--noble-gray-800); - transition: border 0.2s; - cursor: text; - - &::placeholder { - color: var(--noble-gray-600); - } - - &:focus { - border: 1px solid var(--steam-green-800); - } - - @media (hover: hover) { - &:hover { - border: 1px solid var(--steam-green-800); - } - } - - &[type='date'] { - -webkit-appearance: none; - appearance: none; - padding-right: 0; - } - - &[type='date']::-webkit-calendar-picker-indicator { - background-image: url('../../../shared/img/svg/calendar.svg'); - background-position: -3px 0; - cursor: pointer; - } - - &[type='date']::-webkit-inner-spin-button, - &[type='date']::-webkit-outer-spin-button { - display: none; - } - - &::-webkit-datetime-edit-day-field:focus, - &::-webkit-datetime-edit-month-field:focus, - &::-webkit-datetime-edit-year-field:focus { - outline: none; - border-radius: var(--small-br); - color: var(--steam-green-800); - background-color: var(--noble-gray-200); - } - } - button { display: flex; align-items: center; @@ -149,6 +57,99 @@ } } +.input { + border: 1px solid var(--noble-gray-200); + border-radius: var(--small-br); + padding: calc(var(--extra-small-offset) / 2) var(--extra-small-offset); + padding-right: calc(var(--small-offset) * 1.5); + font: var(--regular-font); + letter-spacing: 1px; + color: var(--noble-gray-800); + transition: border 0.2s; + cursor: text; + + &::placeholder { + color: var(--noble-gray-600); + } + + &:focus { + border: 1px solid var(--steam-green-800); + } + + @media (hover: hover) { + &:hover { + border: 1px solid var(--steam-green-800); + } + } + + &[type='date'] { + -webkit-appearance: none; + appearance: none; + padding-right: 0; + } + + &[type='date']::-webkit-calendar-picker-indicator { + background-image: url('../../../shared/img/svg/calendar.svg'); + background-position: -3px 0; + cursor: pointer; + } + + &[type='date']::-webkit-inner-spin-button, + &[type='date']::-webkit-outer-spin-button { + display: none; + } + + &::-webkit-datetime-edit-day-field:focus, + &::-webkit-datetime-edit-month-field:focus, + &::-webkit-datetime-edit-year-field:focus { + outline: none; + border-radius: var(--small-br); + color: var(--steam-green-800); + background-color: var(--noble-gray-200); + } +} + +.showPasswordElement { + position: absolute; + right: 0; + top: 33px; + border-radius: var(--small-br); + padding: calc(var(--extra-small-offset) / 8); + width: 24px; + height: 24px; + background-color: transparent; + transform: translate(-12%, 0); + + svg { + width: 20px; + height: 20px; + stroke: var(--noble-gray-600); + transition: stroke 0.2s; + } + + &:focus { + background-color: var(--noble-gray-200); + + svg { + stroke: var(--steam-green-800); + } + } + + @media (hover: hover) { + &:hover { + background-color: var(--noble-gray-200); + + svg { + stroke: var(--steam-green-800); + } + } + } + + @media (max-width: 768px) { + top: 24px; + } +} + .credentialsWrapper, .personalDataWrapper { display: grid;