Ott 227 add phone code (#45)

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Mirlan 5 years ago committed by GitHub
parent 4053387aaa
commit a66e647106
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/config/lexics/public.tsx
  2. 1
      src/features/Register/components/RegistrationStep/config.tsx
  3. 11
      src/features/Register/components/RegistrationStep/hooks/useCountries.tsx
  4. 18
      src/features/Register/components/RegistrationStep/hooks/useForm.tsx
  5. 4
      src/features/Register/components/RegistrationStep/hooks/useSubmitHandler.tsx
  6. 6
      src/features/Register/components/RegistrationStep/hooks/useValidateForm.tsx
  7. 2
      src/features/Register/components/RegistrationStep/index.tsx
  8. 12
      src/features/Register/helpers/formatPhoneCode/__tests__/index.tsx
  9. 7
      src/features/Register/helpers/formatPhoneCode/index.tsx
  10. 16
      src/features/Register/helpers/isValidPhone/__tests__/index.tsx
  11. 5
      src/features/Register/helpers/isValidPhone/index.tsx
  12. 1
      src/requests/getCountries.tsx

@ -6,6 +6,7 @@ export const publicLexics = {
error_fill_out_this_field: 12933, error_fill_out_this_field: 12933,
error_invalid_email_format: 12908, error_invalid_email_format: 12908,
error_invalid_email_or_password: 2502, error_invalid_email_or_password: 2502,
error_invalid_phone_format: 12946,
error_select_country_first: 12910, error_select_country_first: 12910,
error_simple_password: 12940, error_simple_password: 12940,
form_address1: 12914, form_address1: 12914,

@ -32,7 +32,6 @@ export const simpleValidationFields = [
formIds.country, formIds.country,
formIds.firstname, formIds.firstname,
formIds.lastname, formIds.lastname,
formIds.phone,
formIds.postalCode, formIds.postalCode,
formIds.region, formIds.region,
] ]

@ -7,14 +7,13 @@ import {
import orderBy from 'lodash/orderBy' import orderBy from 'lodash/orderBy'
import map from 'lodash/map' import map from 'lodash/map'
import type { Countries } from 'requests' import type { Countries, Country } from 'requests'
import { getCountries } from 'requests' import { getCountries } from 'requests'
import { useLexicsStore } from 'features/LexicsStore' import { useLexicsStore } from 'features/LexicsStore'
export type Country = { export type SelectedCountry = (Country & {
id: number,
name: string, name: string,
} }) | null
type Names = 'name_eng' | 'name_rus' type Names = 'name_eng' | 'name_rus'
@ -31,14 +30,14 @@ const useCountriesList = () => {
export const useCountries = () => { export const useCountries = () => {
const countries = useCountriesList() const countries = useCountriesList()
const { suffix } = useLexicsStore() const { suffix } = useLexicsStore()
const [selectedCountry, setSelectedCountry] = useState<Country | null>(null) const [selectedCountry, setSelectedCountry] = useState<SelectedCountry>(null)
const nameField = `name_${suffix}` as Names const nameField = `name_${suffix}` as Names
const transformedCountries = useMemo( const transformedCountries = useMemo(
() => orderBy( () => orderBy(
map(countries, (country) => ({ map(countries, (country) => ({
id: country.id, ...country,
name: country[nameField], name: country[nameField],
})), })),
'name', 'name',

@ -5,9 +5,11 @@ import trim from 'lodash/trim'
import { useForm } from 'features/FormStore' import { useForm } from 'features/FormStore'
import { isValidEmail } from 'features/Register/helpers/isValidEmail' import { isValidEmail } from 'features/Register/helpers/isValidEmail'
import { isValidPhone } from 'features/Register/helpers/isValidPhone'
import { formatPhoneCode } from 'features/Register/helpers/formatPhoneCode'
import { formIds } from '../config' import { formIds } from '../config'
import type { Country } from './useCountries' import type { SelectedCountry } from './useCountries'
import { useCountries } from './useCountries' import { useCountries } from './useCountries'
import { useCities } from './useCities' import { useCities } from './useCities'
import { useSubmitHandler } from './useSubmitHandler' import { useSubmitHandler } from './useSubmitHandler'
@ -45,11 +47,22 @@ export const useRegistrationForm = () => {
} }
} }
const onCountrySelect = (country: Country | null) => { const onPhoneBlur = ({ target }: ChangeEvent<HTMLInputElement>) => {
const phone = target.value
if (phone && !isValidPhone(phone)) {
updateFormError(formIds.phone, 'error_invalid_phone_format')
}
}
const onCountrySelect = (country: SelectedCountry) => {
setSelectedCountry(country) setSelectedCountry(country)
updateFormValue(formIds.country)(country?.name || '') updateFormValue(formIds.country)(country?.name || '')
resetCities() resetCities()
resetSelectedCity() resetSelectedCity()
const code = country?.phone_code
? formatPhoneCode(country.phone_code)
: ''
updateFormValue(formIds.phone)(code)
} }
const onRegionOrCityChange = (fieldName: string) => ( const onRegionOrCityChange = (fieldName: string) => (
@ -80,6 +93,7 @@ export const useRegistrationForm = () => {
onCitySelect, onCitySelect,
onCountrySelect, onCountrySelect,
onEmailBlur, onEmailBlur,
onPhoneBlur,
onRegionOrCityChange, onRegionOrCityChange,
readFormError, readFormError,
readFormValue, readFormValue,

@ -8,12 +8,12 @@ import { useAuthStore } from 'features/AuthStore'
import { useForm } from 'features/FormStore' import { useForm } from 'features/FormStore'
import { formIds } from '../config' import { formIds } from '../config'
import type { Country } from './useCountries' import type { SelectedCountry } from './useCountries'
import { useValidateForm } from './useValidateForm' import { useValidateForm } from './useValidateForm'
type Args = { type Args = {
selectedCity: City | null, selectedCity: City | null,
selectedCountry: Country | null, selectedCountry: SelectedCountry,
} }
export const useSubmitHandler = ({ export const useSubmitHandler = ({

@ -4,6 +4,7 @@ import reduce from 'lodash/reduce'
import { useForm } from 'features/FormStore' import { useForm } from 'features/FormStore'
import { isValidEmail } from 'features/Register/helpers/isValidEmail' import { isValidEmail } from 'features/Register/helpers/isValidEmail'
import { isValidPassword } from 'features/Register/helpers/isValidPassword' import { isValidPassword } from 'features/Register/helpers/isValidPassword'
import { isValidPhone } from 'features/Register/helpers/isValidPhone'
import { import {
formIds, formIds,
@ -39,6 +40,7 @@ export const useValidateForm = () => {
let hasError = false let hasError = false
const email = readTrimmedValue(formIds.email) const email = readTrimmedValue(formIds.email)
const password = readTrimmedValue(formIds.password) const password = readTrimmedValue(formIds.password)
const phone = readTrimmedValue(formIds.phone)
if (allFieldsEmpty(requiredFields)) { if (allFieldsEmpty(requiredFields)) {
updateFormError(formIds.formError, 'error_fill_out_required_fields') updateFormError(formIds.formError, 'error_fill_out_required_fields')
setErrorOnEmptyFields(requiredFields, '') setErrorOnEmptyFields(requiredFields, '')
@ -54,6 +56,10 @@ export const useValidateForm = () => {
updateFormError(formIds.password, 'error_simple_password') updateFormError(formIds.password, 'error_simple_password')
hasError = true hasError = true
} }
if (isValidPhone(phone)) {
updateFormError(formIds.phone, 'error_invalid_phone_format')
hasError = true
}
hasError = setErrorOnEmptyFields(simpleValidationFields, 'error_fill_out_this_field') hasError = setErrorOnEmptyFields(simpleValidationFields, 'error_fill_out_this_field')
return !hasError return !hasError
} }

@ -24,6 +24,7 @@ const Registration = () => {
onCitySelect, onCitySelect,
onCountrySelect, onCountrySelect,
onEmailBlur, onEmailBlur,
onPhoneBlur,
onRegionOrCityChange, onRegionOrCityChange,
readFormError, readFormError,
readFormValue, readFormValue,
@ -133,6 +134,7 @@ const Registration = () => {
labelLexic='form_phone' labelLexic='form_phone'
labelWidth={labelWidth} labelWidth={labelWidth}
onChange={updateFormValue(formIds.phone)} onChange={updateFormValue(formIds.phone)}
onBlur={onPhoneBlur}
/> />
<ButtonsBlock> <ButtonsBlock>

@ -0,0 +1,12 @@
import { formatPhoneCode } from '..'
it('returns empty code', () => {
expect(formatPhoneCode('')).toBe('')
expect(formatPhoneCode('+')).toBe('')
expect(formatPhoneCode('abcd')).toBe('')
})
it('returns formatted code', () => {
expect(formatPhoneCode('+1')).toBe('+(1)')
expect(formatPhoneCode('+12345')).toBe('+(12345)')
})

@ -0,0 +1,7 @@
const numberGroup = /(\d+)/
export const formatPhoneCode = (phoneCode: string) => {
const group = phoneCode.match(numberGroup)
const code = group?.[0]
return code ? `+(${code})` : ''
}

@ -0,0 +1,16 @@
import { isValidPhone } from '..'
it('returns false for invalid phones', () => {
expect(isValidPhone('')).toBeFalsy()
expect(isValidPhone('a')).toBeFalsy()
expect(isValidPhone('!@#!$%')).toBeFalsy()
expect(isValidPhone('+(1)123a')).toBeFalsy()
expect(isValidPhone('+(1)-234-5678$')).toBeFalsy()
})
it('returns true for valid phones', () => {
expect(isValidPhone('+(1)')).toBeTruthy()
expect(isValidPhone('+(1)12345')).toBeTruthy()
expect(isValidPhone('+(1) 234 5678')).toBeTruthy()
expect(isValidPhone('+(1)-234-5678')).toBeTruthy()
})

@ -0,0 +1,5 @@
const phoneRegex = /^[0-9+\- ()]{1,500}$/
export const isValidPhone = (phone: string) => (
phoneRegex.test(phone.toLowerCase())
)

@ -9,6 +9,7 @@ export type Country = {
iso_3166_1_alpha_3: string, iso_3166_1_alpha_3: string,
name_eng: string, name_eng: string,
name_rus: string, name_rus: string,
phone_code: string | null,
} }
export type Countries = Array<Country> export type Countries = Array<Country>

Loading…
Cancel
Save