Ott 463 user account fields (#177)

* Ott 463 user account fields 1 (#175)

* fix(ott-463): made some changes in combobox

* fix(ott-463): fixed input and search icon

* fix(ott-463): made some minor changes

* Ott 463 user account fields 2 (#176)

* fix(ott-463): added fields

* fix(ott-463): bug fix

* fix(ott-463): moved hooks from register to common hooks folder

* fix(ott-463): deleted mutation
keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Armen 5 years ago committed by GitHub
parent a89571e5ad
commit affac606b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/config/form.tsx
  2. 2
      src/features/Combobox/components/Arrow/index.tsx
  3. 64
      src/features/Combobox/hooks/index.tsx
  4. 4
      src/features/Combobox/hooks/useKeyboardScroll.tsx
  5. 4
      src/features/Combobox/index.tsx
  6. 3
      src/features/Combobox/styled.tsx
  7. 1
      src/features/Combobox/types.tsx
  8. 4
      src/features/Common/Input/index.tsx
  9. 8
      src/features/Common/Input/styled.tsx
  10. 6
      src/features/Login/hooks.tsx
  11. 2
      src/features/Login/index.tsx
  12. 14
      src/features/Register/components/RegistrationStep/hooks/useSubmitHandler.tsx
  13. 6
      src/features/Register/components/RegistrationStep/index.tsx
  14. 1
      src/features/Search/styled.tsx
  15. 73
      src/features/UserAccount/hooks.tsx
  16. 165
      src/features/UserAccount/index.tsx
  17. 6
      src/features/UserAccount/styled.tsx
  18. 11
      src/features/UserAccount/useValidateForm.tsx
  19. 0
      src/helpers/formatPhoneCode/__tests__/index.tsx
  20. 0
      src/helpers/formatPhoneCode/index.tsx
  21. 0
      src/helpers/isValidEmail/__tests__/index.tsx
  22. 0
      src/helpers/isValidEmail/index.tsx
  23. 0
      src/helpers/isValidPassword/__tests__/index.tsx
  24. 0
      src/helpers/isValidPassword/index.tsx
  25. 0
      src/helpers/isValidPhone/__tests__/index.tsx
  26. 0
      src/helpers/isValidPhone/index.tsx
  27. 21
      src/hooks/useCities.tsx
  28. 76
      src/hooks/useForm.tsx
  29. 8
      src/hooks/useValidateForm.tsx
  30. 6
      src/requests/saveUserInfo.tsx

@ -1,15 +1,17 @@
export const formIds = {
address1: 'address1',
address2: 'address2',
address1: 'address_line1',
address2: 'address_line2',
city: 'city',
cityId: 'cityId',
country: 'country',
countryId: 'countryId',
email: 'email',
firstname: 'firstname',
formError: 'formError',
lastname: 'lastname',
password: 'password',
phone: 'phone',
postalCode: 'postalCode',
postalCode: 'postal_code',
region: 'region',
}

@ -9,7 +9,7 @@ type Props = {
const Wrapper = styled.div<{ isExpanded: boolean }>`
position: absolute;
right: 16px;
right: 22px;
top: 50%;
transform: translateY(-50%);
width: 20px;

@ -1,4 +1,4 @@
import type { ChangeEvent } from 'react'
import type { ChangeEvent, KeyboardEvent } from 'react'
import {
useState,
useCallback,
@ -10,8 +10,9 @@ import toLower from 'lodash/toLower'
import find from 'lodash/find'
import trim from 'lodash/trim'
import size from 'lodash/size'
import isEmpty from 'lodash/isEmpty'
import { useToggle, useEventListener } from 'hooks'
import { useToggle } from 'hooks'
import type { Props, Option } from '../types'
import { matchSort } from '../helpers'
@ -40,7 +41,10 @@ export const useCombobox = <T extends Option>(props: Props<T>) => {
const inputFieldRef = useRef<HTMLInputElement>(null)
const [index, setIndex] = useState(0)
const { onKeyDown, popoverRef } = useKeyboardScroll()
const {
onKeyDownScroll,
popoverRef,
} = useKeyboardScroll()
const {
onQueryChange,
@ -83,25 +87,19 @@ export const useCombobox = <T extends Option>(props: Props<T>) => {
const onOutsideClick = (event: MouseEvent) => {
if (event.target !== inputFieldRef.current as HTMLInputElement) {
close()
if (results[0]?.name.includes(query) && query) {
onOptionSelect(results[0].name)
} else {
onOptionSelect(query)
}
}
}
const optionSelectListener = useCallback((event: KeyboardEvent) => {
if (event.key === 'ArrowUp') {
setIndex(index - 1)
} else if (event.key === 'ArrowDown') {
setIndex(index + 1)
} else if (event.key === 'Enter') {
onSelect?.(results[index])
close()
inputFieldRef.current?.blur()
const onInputBlur = () => {
if (isEmpty(results)) {
onOptionSelect('')
}
}, [
close,
index,
results,
onSelect,
])
}
useEffect(() => {
const lastElementIndex = size(results) - 1
@ -113,28 +111,34 @@ export const useCombobox = <T extends Option>(props: Props<T>) => {
results,
])
useEventListener({
callback: optionSelectListener,
event: 'keydown',
})
const escPressListener = useCallback((event: KeyboardEvent) => {
const onKeyDown = useCallback((event: KeyboardEvent<HTMLInputElement>) => {
onKeyDownScroll(event)
if (event.key === 'Escape') {
close()
inputFieldRef.current?.blur()
} else if (event.key === 'ArrowUp') {
setIndex(index - 1)
} else if (event.key === 'ArrowDown') {
setIndex(index + 1)
} else if (event.key === 'Enter') {
onSelect?.(results[index])
close()
inputFieldRef.current?.blur()
}
}, [close])
useEventListener({
callback: escPressListener,
event: 'keydown',
})
}, [
close,
index,
results,
onSelect,
onKeyDownScroll,
])
return {
close,
index,
inputFieldRef,
isOpen,
onInputBlur,
onKeyDown,
onOptionSelect,
onOutsideClick,

@ -3,7 +3,7 @@ import { useRef } from 'react'
export const useKeyboardScroll = () => {
const popoverRef = useRef<HTMLUListElement>(null)
const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
const onKeyDownScroll = (event: KeyboardEvent<HTMLInputElement>) => {
const container = popoverRef.current
if (event.isDefaultPrevented() || !container) return
@ -24,5 +24,5 @@ export const useKeyboardScroll = () => {
})
}
return { onKeyDown, popoverRef }
return { onKeyDownScroll, popoverRef }
}

@ -30,6 +30,7 @@ export const Combobox = <T extends Option>(props: Props<T>) => {
label,
labelLexic,
labelWidth,
maxLength,
title,
withArrow,
} = props
@ -38,6 +39,7 @@ export const Combobox = <T extends Option>(props: Props<T>) => {
index,
inputFieldRef,
isOpen,
onInputBlur,
onKeyDown,
onOptionSelect,
onOutsideClick,
@ -59,6 +61,8 @@ export const Combobox = <T extends Option>(props: Props<T>) => {
{labelLexic ? <T9n t={labelLexic} /> : label}
</LabelTitle>
<InputStyled
maxLength={maxLength}
onBlur={onInputBlur}
onFocus={open}
ref={inputFieldRef}
autoComplete='off'

@ -14,9 +14,10 @@ export const PopOver = styled.ul`
max-height: 400px;
width: 100%;
top: 55px;
left: 0px;
left: -1px;
overflow: auto;
z-index: 2;
background: rgb(102, 102, 102);
${customScrollbar}
${customStylesMixin}
`

@ -22,6 +22,7 @@ export type Props<T> = Pick<InputHTMLAttributes<HTMLInputElement>, (
label?: string,
labelLexic?: string,
labelWidth?: number,
maxLength?: number,
onChange?: (event: ChangeEvent<HTMLInputElement>) => void,
onSelect?: (option: T | null) => void,
options: Array<T>,

@ -11,12 +11,14 @@ import {
Label,
LabelTitle,
Error,
Icon,
Column,
} from './styled'
type Props = {
autoComplete?: string,
defaultValue?: string,
editIcon?: boolean,
inputWidth?: number,
label?: string,
labelLexic?: string,
@ -35,6 +37,7 @@ type Props = {
export const Input = ({
autoComplete = '',
defaultValue,
editIcon = false,
error,
inputWidth,
label,
@ -81,6 +84,7 @@ export const Input = ({
placeholder={translate(labelLexic || '')}
/>
</Label>
{editIcon && <Icon image='edit-icon' />}
</InputWrapper>
<Error t={error || ''} />
</Column>

@ -174,3 +174,11 @@ export const Error = styled(T9n)<ErrorProps>`
margin-top: 0;
}
`
export const Icon = styled.div<{ image: string }>`
width: 15px;
height: 25px;
background-image: url(/images/${({ image }) => `${image}.svg`});
background-size: 100%;
background-repeat: no-repeat;
`

@ -3,10 +3,12 @@ import type { FormEvent, FocusEvent } from 'react'
import trim from 'lodash/trim'
import isEmpty from 'lodash/isEmpty'
import { formIds } from 'config/form'
import { isValidEmail } from 'helpers/isValidEmail'
import { useAuthStore } from 'features/AuthStore'
import { useForm } from 'features/FormStore'
import { formIds } from 'features/Register/components/RegistrationStep/config'
import { isValidEmail } from 'features/Register/helpers/isValidEmail'
export const useLoginForm = () => {
const {

@ -1,12 +1,12 @@
import React from 'react'
import { PAGES } from 'config'
import { formIds } from 'config/form'
import { T9n } from 'features/T9n'
import { Logo } from 'features/Logo'
import { Input, ButtonSolid } from 'features/Common'
import { Error } from 'features/Common/Input/styled'
import { formIds } from 'features/Register/components/RegistrationStep/config'
import { FormStore } from 'features/FormStore'
import { useLoginForm } from './hooks'

@ -4,12 +4,13 @@ import trim from 'lodash/trim'
import type { City } from 'requests'
import { formIds } from 'config/form'
import { useAuthStore } from 'features/AuthStore'
import { useForm } from 'features/FormStore'
import type { SelectedCountry } from 'hooks/useCountries'
import { formIds } from '../config'
import { useValidateForm } from './useValidateForm'
import { useValidateForm } from 'hooks/useValidateForm'
type Args = {
selectedCity: City | null,
@ -26,11 +27,6 @@ export const useSubmitHandler = ({
const readTrimmedValue = (fieldName: string) => trim(readFormValue(fieldName))
const getCityParams = () => {
if (selectedCity) return { cityId: selectedCity.id }
return { city: readTrimmedValue(formIds.city) }
}
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault()
@ -44,11 +40,13 @@ export const useSubmitHandler = ({
const region = readTrimmedValue(formIds.region)
const address1 = readTrimmedValue(formIds.address1)
const address2 = readTrimmedValue(formIds.address2)
const city = readTrimmedValue(formIds.city)
register({
address1,
address2,
...getCityParams(),
city,
cityId: selectedCity?.id,
countryId: selectedCountry.id,
email,
firstname,

@ -1,5 +1,7 @@
import React from 'react'
import { formIds } from 'config/form'
import { T9n } from 'features/T9n'
import { Combobox } from 'features/Combobox'
import { Input, ButtonSolid } from 'features/Common'
@ -11,8 +13,7 @@ import {
} from 'features/Login/styled'
import { FormStore } from 'features/FormStore'
import { formIds } from './config'
import { useRegistrationForm } from './hooks/useForm'
import { useRegistrationForm } from 'hooks/useForm'
const labelWidth = 116
@ -123,7 +124,6 @@ const Registration = () => {
onChange={updateFormValue(formIds.phone)}
onBlur={onPhoneBlur}
/>
<ButtonsBlock>
<ButtonSolid type='submit'>
<T9n t='next' />

@ -107,6 +107,7 @@ export const Form = styled.form<{isMatch: boolean}>`
::before {
content: '';
display: block;
position: absolute;
width: 25px;
height: 25px;
background-image: url(/images/search.svg);

@ -6,40 +6,38 @@ import {
import forEach from 'lodash/forEach'
import trim from 'lodash/trim'
import isString from 'lodash/isString'
import type { SelectedCountry } from 'hooks/useCountries'
import { useCountries } from 'hooks/useCountries'
import { formIds } from 'config/form'
import type { UserInfo } from 'requests/saveUserInfo'
import { getUserInfo } from 'requests/getUserInfo'
import { saveUserInfo } from 'requests/saveUserInfo'
import type { UserInfo } from 'requests/saveUserInfo'
import { useForm } from 'features/FormStore'
import { useLexicsStore } from 'features/LexicsStore'
import type { SelectedCountry } from 'hooks/useCountries'
import { useRegistrationForm } from 'hooks/useForm'
import { useValidateForm } from './useValidateForm'
import { formIds } from './config'
type Name = 'name_rus' | 'name_eng'
export const useUserInfo = () => {
const {
readFormError,
readFormValue,
updateFormError,
updateFormValue,
} = useForm()
const { suffix } = useLexicsStore()
const validateForm = useValidateForm()
const saveButton = useRef<HTMLButtonElement>(null)
const {
cities,
countries,
setSelectedCountry,
} = useCountries()
getCities,
onCitySelect,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
resetCities,
resetSelectedCity,
selectedCity,
updateFormError,
updateFormValue,
} = useRegistrationForm()
const readTrimmedValue = useCallback(
(fieldName: string) => trim(readFormValue(fieldName)),
@ -54,17 +52,16 @@ export const useUserInfo = () => {
const password = readTrimmedValue(formIds.password)
const postalCode = Number(readTrimmedValue(formIds.postalCode))
const region = readTrimmedValue(formIds.region)
const address_line1 = readTrimmedValue(formIds.address_line1)
const address_line2 = readTrimmedValue(formIds.address_line2)
const address_line1 = readTrimmedValue(formIds.address1)
const address_line2 = readTrimmedValue(formIds.address2)
const city = readTrimmedValue(formIds.city)
const city_id = Number(readTrimmedValue(formIds.city_id))
const countryId = Number(readTrimmedValue(formIds.countryId))
saveUserInfo({
address_line1,
address_line2,
city,
city_id,
cityId: selectedCity?.id || null,
countryId,
firstname,
lastname,
@ -77,40 +74,36 @@ export const useUserInfo = () => {
}, [
readTrimmedValue,
validateForm,
])
const onCountrySelect = useCallback((country: SelectedCountry) => {
setSelectedCountry(country)
const countryName = country ? country[`name_${suffix}` as Name] : ''
updateFormValue(formIds.country)(countryName)
// TO DO пока не решили сбрасываем ли город и адрес
// updateFormValue(formIds.region)('')
updateFormValue(formIds.countryId)(`${country?.id}`)
}, [
setSelectedCountry,
updateFormValue,
suffix,
selectedCity,
])
useEffect(() => {
getUserInfo().then((res: UserInfo) => {
forEach(res, (value: string | number | SelectedCountry, key: string) => {
if (value && typeof value === 'object') {
onCountrySelect(value)
} else if (isString(value)) {
updateFormValue(key)(value)
onCountrySelect(value, false)
} else if (value) {
updateFormValue(key)(String(value))
}
})
})
}, [updateFormValue, onCountrySelect])
return {
cities,
countries,
getCities,
handleSubmit,
onCitySelect,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
resetCities,
resetSelectedCity,
saveButton,
selectedCity,
updateFormError,
updateFormValue,
}

@ -1,6 +1,7 @@
import React from 'react'
import { userAccountLexics } from 'config/lexics/userAccount'
import { formIds } from 'config/form'
import { Background } from 'features/Background'
import { Combobox } from 'features/Combobox'
@ -9,11 +10,11 @@ import { Form } from 'features/Login/styled'
import { T9n } from 'features/T9n'
import { Error } from 'features/Common/Input/styled'
import { useLexicsStore, useLexicsConfig } from 'features/LexicsStore'
import { CardNumber } from './CardNumber'
import { UserAccountButton } from './UserAccountButton'
import { PageTitle } from './PageTitle'
import { UserAccountSubscription } from './UserAccountSubscription'
import { formIds } from './config'
import { TextNoBorder } from './TextNoBorder'
import { useUserInfo } from './hooks'
@ -27,7 +28,7 @@ import {
ButtonWrapper,
} from './styled'
const labelWidth = 78
const labelWidth = 110
export const UserAccount = () => {
useLexicsConfig(userAccountLexics)
@ -35,9 +36,13 @@ export const UserAccount = () => {
const { translate } = useLexicsStore()
const {
cities,
countries,
handleSubmit,
onCitySelect,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
saveButton,
@ -61,6 +66,8 @@ export const UserAccount = () => {
labelWidth={labelWidth}
onChange={updateFormValue(formIds.firstname)}
error={readFormError(formIds.firstname)}
editIcon
maxLength={500}
/>
<Input
value={readFormValue(formIds.lastname)}
@ -68,126 +75,94 @@ export const UserAccount = () => {
labelWidth={labelWidth}
onChange={updateFormValue(formIds.lastname)}
error={readFormError(formIds.lastname)}
editIcon
maxLength={500}
/>
<Input
onBlur={onPhoneBlur}
value={readFormValue(formIds.phone)}
labelLexic='phone'
labelWidth={labelWidth}
onChange={updateFormValue(formIds.phone)}
error={readFormError(formIds.phone)}
editIcon
maxLength={100}
/>
<Input
value={readFormValue(formIds.password)}
error={readFormError(formIds.password)}
type='password'
labelLexic='form_password'
labelWidth={labelWidth}
onChange={updateFormValue(formIds.password)}
editIcon
maxLength={500}
/>
<Combobox
value={readFormValue(formIds.country)}
error={readFormError(formIds.country)}
labelLexic='form_country'
options={countries}
labelWidth={labelWidth}
withArrow
onChange={updateFormValue(formIds.country)}
value={readFormValue(formIds.country)}
error={readFormError(formIds.country)}
options={countries}
onSelect={onCountrySelect}
withArrow
/>
<ButtonWrapper>
<OutlinedButton
type='button'
onClick={handleSubmit}
ref={saveButton}
>
<T9n t='save_changes' />
</OutlinedButton>
<Error t={readFormError(formIds.formError) || ''} />
</ButtonWrapper>
</Form>
</FormWrapper>
<FormWrapper>
<Form>
<UserAccountBlockTitle>
<T9n t='payment' />
</UserAccountBlockTitle>
<CardNumber visa label='1234 1234 1234 1234' />
<CardNumber checked label='1234 1234 1234 1234' />
<CardNumber label='1234 1234 1234 1234' />
<UserAccountButton text={translate('add_card')} />
</Form>
</FormWrapper>
<FormWrapper>
<Form>
<UserAccountBlockTitle>
<T9n t='subscriptions' />
</UserAccountBlockTitle>
<UserAccountSubscription
amount={1999}
checked
inputType='radio'
packageName='Базовая'
packageAction={translate('change')}
/>
<UserAccountSubscription
amount={1999}
checked
inputType='checkbox'
label='Российская Премьер-Лига'
/>
<UserAccountSubscription
amount={499}
checked
inputType='checkbox'
label='Primera División'
/>
<UserAccountSubscription
amount={299}
checked
inputType='checkbox'
label='Manchester United'
/>
<UserAccountButton text={translate('select_subscription')} />
<TextNoBorder
text={`${translate('next_debit')} 31.02.2020`}
amount={4796}
/>
</Form>
</FormWrapper>
</UserAccountFormWrapper>
</UserAccountWrapper>
</Background>
<Background>
<UserAccountWrapper>
<PageTitle titleText={translate('user_account')} />
<UserAccountFormWrapper>
<FormWrapper>
<Form>
<UserAccountBlockTitle>
<T9n t='main' />
</UserAccountBlockTitle>
<Input
labelLexic='name'
value={readFormValue(formIds.postalCode)}
error={readFormError(formIds.postalCode)}
labelLexic='form_postal_code'
labelWidth={labelWidth}
onChange={updateFormValue(formIds.postalCode)}
editIcon
/>
<Input
labelLexic='lastname'
value={readFormValue(formIds.region)}
error={readFormError(formIds.region)}
labelLexic='form_region'
labelWidth={labelWidth}
onChange={onRegionOrCityChange(formIds.region)}
editIcon
maxLength={500}
/>
<Input
labelLexic='phone'
<Combobox
value={readFormValue(formIds.city)}
error={readFormError(formIds.city)}
labelLexic='form_city'
labelWidth={labelWidth}
onChange={onRegionOrCityChange(formIds.city)}
options={cities}
onSelect={onCitySelect}
maxLength={500}
/>
<Input
type='email'
labelLexic='mail'
value={readFormValue(formIds.address1)}
error={readFormError(formIds.address1)}
labelLexic='form_address1'
labelWidth={labelWidth}
onChange={updateFormValue(formIds.address1)}
editIcon
maxLength={500}
/>
<Combobox
labelLexic='form_country'
options={countries}
<Input
value={readFormValue(formIds.address2)}
error={readFormError(formIds.address2)}
labelLexic='form_address2'
labelWidth={labelWidth}
withArrow
onChange={updateFormValue(formIds.country)}
value={readFormValue(formIds.country)}
error={readFormError(formIds.country)}
onSelect={onCountrySelect}
onChange={updateFormValue(formIds.address2)}
editIcon
maxLength={500}
/>
<OutlinedButton>
<T9n t='save_changes' />
</OutlinedButton>
<ButtonWrapper>
<OutlinedButton
type='button'
onClick={handleSubmit}
ref={saveButton}
>
<T9n t='save_changes' />
</OutlinedButton>
<Error t={readFormError(formIds.formError) || ''} />
</ButtonWrapper>
</Form>
</FormWrapper>
<FormWrapper>

@ -8,8 +8,10 @@ export const OutlinedButton = styled.button`
width: 288px;
margin-top: 20px;
align-self: flex-start;
color: #005EDD;
border-color: #005EDD;
color: white;
font-weight: bold;
border-color: #0033CC;
background-color: #0033CC;
&:hover {
cursor: pointer;

@ -2,13 +2,14 @@ import trim from 'lodash/trim'
import reduce from 'lodash/reduce'
import { useForm } from 'features/FormStore'
import { isValidPhone } from 'features/Register/helpers/isValidPhone'
import { isValidPhone } from 'helpers/isValidPhone'
import { isValidPassword } from 'helpers/isValidPassword'
import {
formIds,
requiredFields,
simpleValidationFields,
} from './config'
} from 'config/form'
export const useValidateForm = () => {
const {
@ -37,6 +38,7 @@ export const useValidateForm = () => {
const validateForm = () => {
let hasError = false
const phone = readTrimmedValue(formIds.phone)
const password = readTrimmedValue(formIds.password)
if (allFieldsEmpty(requiredFields)) {
updateFormError(formIds.formError, 'error_fill_out_required_fields')
@ -46,6 +48,11 @@ export const useValidateForm = () => {
hasError = setErrorOnEmptyFields(simpleValidationFields, 'error_fill_out_this_field')
if (!isValidPassword(password)) {
updateFormError(formIds.password, 'error_simple_password')
hasError = true
}
if (!isValidPhone(phone)) {
updateFormError(formIds.phone, 'error_invalid_phone_format')
hasError = true

@ -7,23 +7,24 @@ import debounce from 'lodash/debounce'
import type { Cities, City } from 'requests'
import { getCountryCities } from 'requests'
import { useForm } from 'features/FormStore'
import { formIds } from '../config'
import { formIds } from 'config/form'
import { useForm } from 'features/FormStore'
const useCitiesList = () => {
const [cities, setCities] = useState<Cities>([])
const getCities = (city: string, selectedCountryId: number) => {
const getCities = useCallback((city: string, selectedCountryId: number) => {
getCountryCities(city, selectedCountryId).then(setCities)
}
}, [])
const getCitiesDebounced = useCallback(
debounce(getCities, 300),
debounce(getCities, 500),
[],
)
const resetCities = () => setCities([])
const resetCities = useCallback(() => setCities([]), [])
return {
cities,
@ -44,19 +45,19 @@ export const useCities = () => {
resetCities,
} = useCitiesList()
const onCitySelect = (newCity: City | null) => {
const onCitySelect = useCallback((newCity: City | null) => {
if (newCity) {
setCityQuery(newCity.name)
setSelectedCity(newCity)
} else {
setSelectedCity(null)
}
}
}, [setCityQuery])
const resetSelectedCity = () => {
const resetSelectedCity = useCallback(() => {
setCityQuery('')
setSelectedCity(null)
}
}, [setCityQuery])
return {
cities,

@ -1,18 +1,26 @@
import type { ChangeEvent, FocusEvent } from 'react'
import { useEffect } from 'react'
import {
useEffect,
useCallback,
} from 'react'
import trim from 'lodash/trim'
import { useForm } from 'features/FormStore'
import { isValidEmail } from 'features/Register/helpers/isValidEmail'
import { isValidPhone } from 'features/Register/helpers/isValidPhone'
import { formatPhoneCode } from 'features/Register/helpers/formatPhoneCode'
import { isValidEmail } from 'helpers/isValidEmail'
import { isValidPhone } from 'helpers/isValidPhone'
import { formatPhoneCode } from 'helpers/formatPhoneCode'
import type { SelectedCountry } from 'hooks/useCountries'
import { useCountries } from 'hooks/useCountries'
import { formIds } from '../config'
import { useCities } from './useCities'
import { useSubmitHandler } from './useSubmitHandler'
import { useCities } from 'hooks/useCities'
import { formIds } from 'config/form'
import { useForm } from 'features/FormStore'
import { useSubmitHandler } from 'features/Register/components/RegistrationStep/hooks/useSubmitHandler'
import { useLexicsStore } from 'features/LexicsStore'
type Name = 'name_rus' | 'name_eng'
export const useRegistrationForm = () => {
const {
@ -41,33 +49,50 @@ export const useRegistrationForm = () => {
selectedCity,
selectedCountry,
})
const { suffix } = useLexicsStore()
const onEmailBlur = ({ target }: FocusEvent<HTMLInputElement>) => {
const onEmailBlur = useCallback(({ target }: FocusEvent<HTMLInputElement>) => {
const email = trim(target.value)
if (email && !isValidEmail(email)) {
updateFormError(formIds.email, 'error_invalid_email_format')
}
}
}, [updateFormError])
const onPhoneBlur = ({ target }: ChangeEvent<HTMLInputElement>) => {
const onPhoneBlur = useCallback(({ target }: ChangeEvent<HTMLInputElement>) => {
const phone = target.value
if (phone && !isValidPhone(phone)) {
updateFormError(formIds.phone, 'error_invalid_phone_format')
}
}
}, [updateFormError])
const onCountrySelect = (country: SelectedCountry) => {
const onCountrySelect = useCallback((
country: SelectedCountry,
updatePhoneCode: boolean = true,
) => {
setSelectedCountry(country)
updateFormValue(formIds.country)(country?.name || '')
const countryName = country ? country[`name_${suffix}` as Name] : ''
updateFormValue(formIds.country)(countryName)
updateFormValue(formIds.cityId)('')
updateFormValue(formIds.countryId)(`${country?.id}`)
resetCities()
resetSelectedCity()
const code = country?.phone_code
? formatPhoneCode(country.phone_code)
: ''
updateFormValue(formIds.phone)(code)
}
const onRegionOrCityChange = (fieldName: string) => (
if (updatePhoneCode) {
const code = country?.phone_code
? formatPhoneCode(country.phone_code)
: ''
updateFormValue(formIds.phone)(code)
}
}, [
resetCities,
resetSelectedCity,
setSelectedCountry,
updateFormValue,
suffix,
])
const onRegionOrCityChange = useCallback((fieldName: string) => (
({ target }: ChangeEvent<HTMLInputElement>) => {
if (selectedCountry) {
updateFormValue(fieldName)(target.value)
@ -75,7 +100,11 @@ export const useRegistrationForm = () => {
updateFormError(formIds.country, 'error_select_country_first')
}
}
)
), [
selectedCountry,
updateFormError,
updateFormValue,
])
const trimmedCity = trim(readFormValue(formIds.city))
useEffect(() => {
@ -91,6 +120,7 @@ export const useRegistrationForm = () => {
return {
cities,
countries,
getCities,
handleSubmit,
onCitySelect,
onCountrySelect,
@ -99,6 +129,10 @@ export const useRegistrationForm = () => {
onRegionOrCityChange,
readFormError,
readFormValue,
resetCities,
resetSelectedCity,
selectedCity,
updateFormError,
updateFormValue,
}
}

@ -2,15 +2,15 @@ import trim from 'lodash/trim'
import reduce from 'lodash/reduce'
import { useForm } from 'features/FormStore'
import { isValidEmail } from 'features/Register/helpers/isValidEmail'
import { isValidPassword } from 'features/Register/helpers/isValidPassword'
import { isValidPhone } from 'features/Register/helpers/isValidPhone'
import { isValidEmail } from 'helpers/isValidEmail'
import { isValidPassword } from 'helpers/isValidPassword'
import { isValidPhone } from 'helpers/isValidPhone'
import {
formIds,
requiredFields,
simpleValidationFields,
} from '../config'
} from 'config/form'
export const useValidateForm = () => {
const {

@ -10,7 +10,7 @@ export type UserInfo = {
address_line1: string,
address_line2: string,
city: string,
city_id: number,
cityId: number | null,
countryId: number,
firstname: string,
lastname: string,
@ -34,7 +34,7 @@ export const saveUserInfo = async ({
address_line1,
address_line2,
city,
city_id,
cityId,
countryId,
firstname,
lastname,
@ -49,7 +49,7 @@ export const saveUserInfo = async ({
_p_address_line1: address_line1,
_p_address_line2: address_line2,
_p_city: city,
_p_city_id: city_id,
_p_city_id: cityId,
_p_country_id: countryId,
_p_firstname: firstname,
_p_lastname: lastname,

Loading…
Cancel
Save