refactor(869): user account form refactor and bug fixes (#322)

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Mirlan 5 years ago committed by GitHub
parent 07ba41b100
commit b717e2a1e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 26
      src/config/form.tsx
  2. 5
      src/features/Combobox/hooks/index.tsx
  3. 22
      src/features/FormStore/helpers.tsx
  4. 62
      src/features/FormStore/hooks/useFormState.tsx
  5. 5
      src/features/FormStore/index.tsx
  6. 74
      src/features/UserAccount/components/PagePersonalInfo/hooks/index.tsx
  7. 137
      src/features/UserAccount/components/PagePersonalInfo/hooks/useUserInfo.tsx
  8. 160
      src/features/UserAccount/components/PagePersonalInfo/index.tsx
  9. 27
      src/features/UserAccount/components/PersonalInfoForm/hooks/useCities.tsx
  10. 39
      src/features/UserAccount/components/PersonalInfoForm/hooks/useCountries.tsx
  11. 98
      src/features/UserAccount/components/PersonalInfoForm/hooks/useUserInfo.tsx
  12. 17
      src/features/UserAccount/components/PersonalInfoForm/hooks/useUserInfoForm.tsx
  13. 0
      src/features/UserAccount/components/PersonalInfoForm/hooks/useValidateForm.tsx
  14. 158
      src/features/UserAccount/components/PersonalInfoForm/index.tsx
  15. 0
      src/features/UserAccount/components/PersonalInfoForm/styled.tsx
  16. 27
      src/features/UserAccount/index.tsx
  17. 18
      src/requests/getUserInfo.tsx
  18. 11
      src/requests/saveUserInfo.tsx

@ -2,38 +2,16 @@ export const formIds = {
address1: 'address_line1',
address2: 'address_line2',
city: 'city',
cityId: 'cityId',
cityId: 'city_id',
country: 'country',
countryId: 'countryId',
email: 'email',
firstname: 'firstname',
formError: 'formError',
initialCountryId: 'initialCountryId',
lastname: 'lastname',
password: 'password',
phone: 'phone',
postalCode: 'postal_code',
region: 'region',
}
export const requiredFields = [
formIds.address1,
formIds.city,
formIds.country,
formIds.email,
formIds.firstname,
formIds.lastname,
formIds.password,
formIds.phone,
formIds.postalCode,
formIds.region,
]
export const simpleValidationFields = [
formIds.address1,
formIds.city,
formIds.country,
formIds.firstname,
formIds.lastname,
formIds.postalCode,
formIds.region,
]

@ -69,7 +69,9 @@ export const useCombobox = <T extends Option>({
const onQueryChange = (e: ChangeEvent<HTMLInputElement>) => {
onChange?.(e)
onSelect?.(null)
if (selected && onSelect) {
onSelect(null)
}
}
const onOptionSelect = useCallback((option: string, e?: BaseSyntheticEvent) => {
@ -95,7 +97,6 @@ export const useCombobox = <T extends Option>({
// если кликали элемент списка то событие обрабатывает onOptionSelect
if (isOptionClicked(target)) return
onOptionSelect(query)
onBlur?.(event)
}

@ -0,0 +1,22 @@
import includes from 'lodash/includes'
import every from 'lodash/every'
import { formIds } from 'config/form'
import type { FormState } from './hooks/useFormState'
const ignoredFields = [formIds.initialCountryId, formIds.country]
export const isFormStateEqual = (state1: FormState, state2: FormState) => (
every(state1, (_, key) => {
if (includes(ignoredFields, key)) return true
const cityId1 = state1[formIds.cityId]?.value
const cityId2 = state2[formIds.cityId]?.value
if (key === formIds.city && cityId1 && cityId2) {
return cityId1 === cityId2
}
return state1[key]?.value === state2[key]?.value
})
)

@ -2,39 +2,18 @@ import type { ChangeEvent } from 'react'
import { useCallback, useState } from 'react'
import isObject from 'lodash/isObject'
import isEqual from 'lodash/isEqual'
import omit from 'lodash/omit'
import { isFormStateEqual } from '../helpers'
type FieldState = {
error: string | null,
error?: string | null,
value: string,
}
type FormState = {[formId: string]: FieldState}
type SimilarState = {[formId: string]: string}
export type FormState = {[formId: string]: FieldState}
export const useFormState = () => {
let init = JSON.parse(localStorage.getItem('init') as string)
const countryID = init === null ? '' : init.country.id
if (init !== null) {
init.address_line1 = init.address_line1 ?? ''
init.address_line2 = init.address_line2 ?? ''
if (init.city_id !== undefined) {
init.city_id = init.city_id ?? ''
}
init.city = init.city ?? ''
init.countryId = `${countryID}`
init.cityId = init.city_id ?? ''
init.firstname = init.firstname ?? ''
init.lastname = init.lastname ?? ''
init.region = init.region ?? ''
init.postal_code = String(init.postal_code) ?? ''
init = omit(init, ['city_id', 'email', 'password', 'postalCode'])
}
const [formState, setFormState] = useState<FormState>({})
const [stateForSimilar, setStateForSimilar] = useState<SimilarState>(init)
const isDiff = isEqual(stateForSimilar, init)
localStorage.setItem('disabled', JSON.stringify(isDiff))
export const useFormState = (initialState: FormState = {}) => {
const [formState, setFormState] = useState<FormState>(initialState)
const readFormValue = useCallback(
(fieldName: string) => formState[fieldName]?.value ?? '',
[formState],
@ -52,32 +31,11 @@ export const useFormState = () => {
...state,
[fieldName]: {
error: null,
value,
value: value ?? '',
},
}
return newState
}))
setStateForSimilar(((state) => {
if (fieldName === 'email') {
return {
...state,
}
}
if (fieldName === 'city_id') {
return {
...state,
}
}
if (fieldName === 'password') {
return {
...state,
}
}
return {
...state,
[fieldName]: value,
}
}))
}
),
[],
@ -99,7 +57,13 @@ export const useFormState = () => {
[],
)
const hasChanges = useCallback(
() => !isFormStateEqual(formState, initialState),
[formState, initialState],
)
return {
hasChanges,
readFormError,
readFormValue,
updateFormError,

@ -1,11 +1,13 @@
import type { ReactNode } from 'react'
import { createContext, useContext } from 'react'
import type { FormState } from './hooks/useFormState'
import { useFormState } from './hooks/useFormState'
type Context = ReturnType<typeof useFormState>
type Props = {
children: ReactNode,
initialState?: FormState,
}
const FormContext = createContext({} as Context)
@ -17,8 +19,9 @@ const FormContext = createContext({} as Context)
*/
export const FormStore = ({
children,
initialState,
}: Props) => {
const formState = useFormState()
const formState = useFormState(initialState)
return (
<FormContext.Provider value={formState}>
{children}

@ -0,0 +1,74 @@
import {
useState,
useEffect,
useCallback,
} from 'react'
import find from 'lodash/find'
import reduce from 'lodash/reduce'
import isNull from 'lodash/isNull'
import isNumber from 'lodash/isNumber'
import isString from 'lodash/isString'
import isObject from 'lodash/isObject'
import { formIds } from 'config/form'
import type { UserInfo, SaveUserInfo } from 'requests'
import {
getUserInfo,
getCountryCities,
saveUserInfo,
} from 'requests'
import type { FormState } from 'features/FormStore/hooks/useFormState'
const transformToFormState = async (userInfo: UserInfo) => {
const cities = userInfo.country?.id
? await getCountryCities('', userInfo.country.id)
: []
return reduce(
formIds,
(
acc: FormState,
field,
) => {
const key = field as keyof UserInfo
const value = userInfo[key]
if (key === formIds.cityId && value) {
const city = find(cities, { id: Number(value) }) || { id: '', name: acc[formIds.city]?.value }
acc[formIds.cityId] = { value: String(city.id) }
acc[formIds.city] = { value: city.name }
} else if (key === formIds.country && isObject(value) && value.id) {
const formValue = { value: String(value.id) }
acc[formIds.initialCountryId] = formValue
acc[formIds.countryId] = formValue
} else if (isNumber(value) || isString(value)) {
acc[key] = { value: String(value) }
} else if (isNull(value)) {
acc[key] = { value: '' }
}
return acc
},
{},
)
}
export const useUserInfo = () => {
const [userInfo, setUserInfo] = useState<FormState>()
const fetchUserInfo = useCallback(() => {
getUserInfo()
.then((data) => transformToFormState(data))
.then(setUserInfo)
}, [])
const onSubmit = useCallback((data: SaveUserInfo) => {
saveUserInfo(data).then(fetchUserInfo)
}, [fetchUserInfo])
useEffect(() => {
fetchUserInfo()
}, [fetchUserInfo])
return { onSubmit, userInfo }
}

@ -1,137 +0,0 @@
import {
useEffect,
useCallback,
useRef,
} from 'react'
import forEach from 'lodash/forEach'
import trim from 'lodash/trim'
import { formIds } from 'config/form'
import { getUserInfo } from 'requests/getUserInfo'
import { saveUserInfo } from 'requests/saveUserInfo'
import { City, getCountryCities } from 'requests/getCountryCities'
import { useLexicsStore } from 'features/LexicsStore'
import type { SelectedCountry } from './useCountries'
import type { Name } from './useUserInfoForm'
import { useUserInfoForm } from './useUserInfoForm'
import { useValidateForm } from './useValidateForm'
export const useUserInfo = () => {
const validateForm = useValidateForm()
const saveButton = useRef<HTMLButtonElement>(null)
const { suffix } = useLexicsStore()
const {
cities,
countries,
onCitySelect,
onCountryBlur,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
selectedCity,
selectedCountry,
setSelectedCountry,
updateFormValue,
} = useUserInfoForm()
const readTrimmedValue = useCallback(
(fieldName: string) => trim(readFormValue(fieldName)) || null,
[readFormValue],
)
const handleSubmit = useCallback(() => {
if (validateForm()) {
const firstname = readTrimmedValue(formIds.firstname)
const lastname = readTrimmedValue(formIds.lastname)
const phone = readTrimmedValue(formIds.phone)
const password = readTrimmedValue(formIds.password)
const postalCode = Number(readTrimmedValue(formIds.postalCode))
const region = readTrimmedValue(formIds.region)
const address_line1 = readTrimmedValue(formIds.address1)
const address_line2 = readTrimmedValue(formIds.address2)
const city = readTrimmedValue(formIds.city)
const countryId = Number(readTrimmedValue(formIds.countryId))
const newUserInfo = {
address_line1,
address_line2,
city,
cityId: selectedCity?.id || null,
countryId,
firstname,
lastname,
password,
phone,
postalCode,
region,
}
const newUserInfoForStorage = {
...newUserInfo,
country: JSON.parse(localStorage.getItem('initCountry') as string),
}
localStorage.setItem('init', JSON.stringify(newUserInfoForStorage))
localStorage.setItem('disabled', 'true')
saveUserInfo(newUserInfo).then(() => saveButton?.current?.blur())
}
}, [
readTrimmedValue,
validateForm,
selectedCity,
])
useEffect(() => {
getUserInfo().then((res: any) => {
const response = res
const convertResponse = () => {
forEach(response, (value: string | number | SelectedCountry, key: string) => {
if (value && typeof value === 'object') {
setSelectedCountry({
...value,
name: value[`name_${suffix}` as Name],
})
updateFormValue(formIds.countryId)(String(value.id))
} else if (value) {
updateFormValue(key)(String(value))
}
})
}
if (response.city === null && response.city_id !== null) {
getCountryCities('', response.country.id).then((resp) => {
const initCity = resp.find((i:City) => i.id.toString() === response.city_id.toString())
if (initCity !== undefined) {
response.city = initCity.name
localStorage.setItem('init', JSON.stringify(res))
convertResponse()
}
})
return
}
localStorage.setItem('init', JSON.stringify(response))
convertResponse()
})
}, [
suffix,
updateFormValue,
setSelectedCountry,
])
return {
cities,
countries,
handleSubmit,
onCitySelect,
onCountryBlur,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
saveButton,
selectedCountry,
updateFormValue,
}
}

@ -1,158 +1,14 @@
import { formIds } from 'config/form'
import { FormStore } from 'features/FormStore'
import { Combobox } from 'features/Combobox'
import { Input } from 'features/Common'
import { T9n } from 'features/T9n'
import { Error } from 'features/Common/Input/styled'
import { useState } from 'react'
import { useUserInfo } from './hooks/useUserInfo'
import { SolidButton } from '../../styled'
import { Form, ButtonWrapper } from './styled'
const labelWidth = 104
const {
address1,
address2,
city,
country,
firstname,
formError,
lastname,
password,
phone,
region,
} = formIds
import { useUserInfo } from './hooks'
import { PersonalInfoForm } from '../PersonalInfoForm'
export const PagePersonalInfo = () => {
const {
cities,
countries,
handleSubmit,
onCitySelect,
onCountryBlur,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
saveButton,
selectedCountry,
updateFormValue,
} = useUserInfo()
const [state, setState] = useState(true)
const isDisabled = JSON.parse(localStorage.getItem('disabled') as string)
const { onSubmit, userInfo } = useUserInfo()
if (!userInfo) return null
return (
<Form>
<Input
value={readFormValue(firstname)}
labelLexic='name'
autoComplete='given-name'
labelWidth={labelWidth}
onChange={updateFormValue(firstname)}
editIcon
maxLength={500}
withError={false}
/>
<Input
value={readFormValue(lastname)}
labelLexic='lastname'
autoComplete='family-name'
labelWidth={labelWidth}
onChange={updateFormValue(lastname)}
editIcon
maxLength={500}
withError={false}
/>
<Input
value={readFormValue(password)}
error={readFormError(password)}
type='password'
autoComplete='new-password'
labelLexic='form_password'
labelWidth={labelWidth}
onChange={updateFormValue(password)}
editIcon
maxLength={500}
withError={false}
/>
<Input
onBlur={onPhoneBlur}
value={readFormValue(phone)}
labelLexic='phone'
autoComplete='tel'
labelWidth={labelWidth}
onChange={updateFormValue(phone)}
error={readFormError(phone)}
editIcon
maxLength={100}
withError={false}
/>
<Combobox
value={selectedCountry?.name ?? readFormValue(country)}
labelLexic='form_country'
labelWidth={labelWidth}
onChange={updateFormValue(country)}
onBlur={onCountryBlur}
options={countries}
onSelect={onCountrySelect}
withError={false}
selected={Boolean(selectedCountry)}
/>
<Input
value={readFormValue(region)}
labelLexic='form_region'
labelWidth={labelWidth}
onChange={onRegionOrCityChange(region)}
editIcon
maxLength={500}
withError={false}
/>
<Combobox
value={readFormValue(city)}
labelLexic='form_city'
labelWidth={labelWidth}
onChange={onRegionOrCityChange(city)}
options={cities}
onSelect={onCitySelect}
maxLength={500}
withError={false}
/>
<Input
value={readFormValue(address1)}
labelLexic='form_address1'
labelWidth={labelWidth}
autoComplete='address-line1'
onChange={updateFormValue(address1)}
editIcon
maxLength={500}
withError={false}
/>
<Input
value={readFormValue(address2)}
labelLexic='form_address2'
labelWidth={labelWidth}
autoComplete='address-line2'
onChange={updateFormValue(address2)}
editIcon
maxLength={500}
withError={false}
/>
<ButtonWrapper>
<SolidButton
disabled={isDisabled}
type='button'
onClick={() => { handleSubmit(); setState((!state)) }}
ref={saveButton}
>
<T9n t='save_changes' />
</SolidButton>
<Error t={readFormError(formError) || ''} />
</ButtonWrapper>
</Form>
<FormStore initialState={userInfo}>
<PersonalInfoForm onSubmit={onSubmit} />
</FormStore>
)
}

@ -1,3 +1,4 @@
import type { FocusEvent } from 'react'
import {
useMemo,
useState,
@ -36,12 +37,6 @@ const useCitiesList = () => {
export const useCities = () => {
const { updateFormValue } = useForm()
const [selectedCity, setSelectedCity] = useState<City | null>(null)
const setCityQuery = useMemo(
() => updateFormValue(formIds.city),
[updateFormValue],
)
const {
cities,
@ -51,24 +46,28 @@ export const useCities = () => {
const onCitySelect = useCallback((newCity: City | null) => {
if (newCity) {
setCityQuery(newCity.name)
setSelectedCity(newCity)
updateFormValue(formIds.city)(newCity.name)
updateFormValue(formIds.cityId)(String(newCity.id))
} else {
setSelectedCity(null)
updateFormValue(formIds.cityId)('')
}
}, [setCityQuery])
}, [updateFormValue])
const resetSelectedCity = useCallback(() => {
setCityQuery('')
setSelectedCity(null)
}, [setCityQuery])
updateFormValue(formIds.city)('')
updateFormValue(formIds.cityId)('')
}, [updateFormValue])
const onCityBlur = (e: FocusEvent<HTMLInputElement>) => {
updateFormValue(formIds.city)(e.target.value ?? '')
}
return {
cities,
getCities,
onCityBlur,
onCitySelect,
resetCities,
resetSelectedCity,
selectedCity,
}
}

@ -5,11 +5,16 @@ import {
} from 'react'
import orderBy from 'lodash/orderBy'
import find from 'lodash/find'
import map from 'lodash/map'
import type { Countries, Country } from 'requests'
import { getCountries } from 'requests'
import { formIds } from 'config/form'
import { useLexicsStore } from 'features/LexicsStore'
import { useForm } from 'features/FormStore'
export type SelectedCountry = (Country & {
name: string,
@ -28,29 +33,37 @@ const useCountriesList = () => {
}
export const useCountries = () => {
const { readFormValue, updateFormValue } = useForm()
const countries = useCountriesList()
const { suffix } = useLexicsStore()
const [selectedCountry, setSelectedCountry] = useState<SelectedCountry>(null)
const nameField = `name_${suffix}` as Names
const initCountry = {
id: selectedCountry?.id,
name_eng: selectedCountry?.name_eng,
name_rus: selectedCountry?.name_rus,
}
localStorage.setItem('initCountry', JSON.stringify(initCountry))
const transformedCountries = useMemo(
() => orderBy(
map(countries, (country) => ({
...country,
name: country[nameField],
})),
'name',
map(countries, (country) => {
const nameField = `name_${suffix}` as Names
return {
...country,
name: country[nameField],
}
}),
({ name }) => name,
),
[countries, nameField],
[countries, suffix],
)
const onCountryBlur = () => {
updateFormValue(formIds.country)('')
}
const countryId = readFormValue(formIds.initialCountryId)
useEffect(() => {
const initialCountry = find(transformedCountries, { id: Number(countryId) })
setSelectedCountry(initialCountry || null)
}, [transformedCountries, countryId])
return {
countries: transformedCountries,
onCountryBlur,
selectedCountry,
setSelectedCountry,
}

@ -0,0 +1,98 @@
import { useCallback } from 'react'
import trim from 'lodash/trim'
import { formIds } from 'config/form'
import type { SaveUserInfo } from 'requests/saveUserInfo'
import { useForm } from 'features/FormStore'
import { useUserInfoForm } from './useUserInfoForm'
import { useValidateForm } from './useValidateForm'
export type Props = {
onSubmit: (data: SaveUserInfo) => void,
}
export const useUserInfo = ({ onSubmit }: Props) => {
const {
hasChanges,
readFormError,
readFormValue,
updateFormValue,
} = useForm()
const validateForm = useValidateForm()
const {
cities,
countries,
onCityBlur,
onCitySelect,
onCountryBlur,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
selectedCountry,
} = useUserInfoForm()
const readTrimmedValue = useCallback(
(fieldName: string) => trim(readFormValue(fieldName)) || null,
[readFormValue],
)
const readNumberValue = useCallback(
(fieldName: string) => {
const value = readTrimmedValue(fieldName)
return value ? Number(value) : null
},
[readTrimmedValue],
)
const handleSubmit = useCallback(() => {
if (validateForm()) {
const firstname = readTrimmedValue(formIds.firstname)
const lastname = readTrimmedValue(formIds.lastname)
const phone = readTrimmedValue(formIds.phone)
const password = readTrimmedValue(formIds.password)
const postalCode = readNumberValue(formIds.postalCode)
const region = readTrimmedValue(formIds.region)
const address_line1 = readTrimmedValue(formIds.address1)
const address_line2 = readTrimmedValue(formIds.address2)
const city = readTrimmedValue(formIds.city)
const cityId = readNumberValue(formIds.cityId)
const countryId = readNumberValue(formIds.countryId)
onSubmit({
address_line1,
address_line2,
city: cityId ? null : city,
cityId,
countryId,
firstname,
lastname,
password,
phone,
postalCode,
region,
})
}
}, [
onSubmit,
readTrimmedValue,
readNumberValue,
validateForm,
])
return {
cities,
countries,
handleSubmit,
hasChanges,
onCityBlur,
onCitySelect,
onCountryBlur,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
selectedCountry,
updateFormValue,
}
}

@ -17,11 +17,8 @@ import type { SelectedCountry } from './useCountries'
import { useCountries } from './useCountries'
import { useCities } from './useCities'
export type Name = 'name_rus' | 'name_eng'
export const useUserInfoForm = () => {
const {
readFormError,
readFormValue,
updateFormError,
updateFormValue,
@ -29,6 +26,7 @@ export const useUserInfoForm = () => {
const {
countries,
onCountryBlur,
selectedCountry,
setSelectedCountry,
} = useCountries()
@ -36,10 +34,10 @@ export const useUserInfoForm = () => {
const {
cities,
getCities,
onCityBlur,
onCitySelect,
resetCities,
resetSelectedCity,
selectedCity,
} = useCities()
const onPhoneBlur = useCallback(({ target }: ChangeEvent<HTMLInputElement>) => {
@ -54,9 +52,9 @@ export const useUserInfoForm = () => {
if (country?.id === selectedCountry?.id) return
setSelectedCountry(country)
updateFormValue(formIds.countryId)(country?.id ? String(country?.id) : '')
updateFormValue(formIds.cityId)('')
updateFormValue(formIds.region)('')
resetCities()
resetSelectedCity()
@ -79,10 +77,6 @@ export const useUserInfoForm = () => {
updateFormValue,
])
const onCountryBlur = () => {
updateFormValue(formIds.country)(selectedCountry?.name || '')
}
const onRegionOrCityChange = useCallback((fieldName: string) => (
({ target }: ChangeEvent<HTMLInputElement>) => {
if (selectedCountry) {
@ -111,14 +105,13 @@ export const useUserInfoForm = () => {
return {
cities,
countries,
onCityBlur,
onCitySelect,
onCountryBlur,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
selectedCity,
selectedCountry,
setSelectedCountry,
updateFormValue,

@ -0,0 +1,158 @@
import { formIds } from 'config/form'
import { Combobox } from 'features/Combobox'
import { Input } from 'features/Common'
import { T9n } from 'features/T9n'
import { Error } from 'features/Common/Input/styled'
import type { Props } from './hooks/useUserInfo'
import { useUserInfo } from './hooks/useUserInfo'
import { SolidButton } from '../../styled'
import { Form, ButtonWrapper } from './styled'
const labelWidth = 104
const {
address1,
address2,
city,
cityId,
country,
firstname,
formError,
lastname,
password,
phone,
region,
} = formIds
export const PersonalInfoForm = (props: Props) => {
const {
cities,
countries,
handleSubmit,
hasChanges,
onCityBlur,
onCitySelect,
onCountryBlur,
onCountrySelect,
onPhoneBlur,
onRegionOrCityChange,
readFormError,
readFormValue,
selectedCountry,
updateFormValue,
} = useUserInfo(props)
return (
<Form>
<Input
value={readFormValue(firstname)}
labelLexic='name'
autoComplete='given-name'
labelWidth={labelWidth}
onChange={updateFormValue(firstname)}
editIcon
maxLength={500}
withError={false}
/>
<Input
value={readFormValue(lastname)}
labelLexic='lastname'
autoComplete='family-name'
labelWidth={labelWidth}
onChange={updateFormValue(lastname)}
editIcon
maxLength={500}
withError={false}
/>
<Input
value={readFormValue(password)}
error={readFormError(password)}
type='password'
autoComplete='new-password'
labelLexic='form_password'
labelWidth={labelWidth}
onChange={updateFormValue(password)}
editIcon
maxLength={500}
withError={false}
/>
<Input
onBlur={onPhoneBlur}
value={readFormValue(phone)}
labelLexic='phone'
autoComplete='tel'
labelWidth={labelWidth}
onChange={updateFormValue(phone)}
error={readFormError(phone)}
editIcon
maxLength={100}
withError={false}
/>
<Combobox
value={selectedCountry?.name ?? readFormValue(country)}
labelLexic='form_country'
labelWidth={labelWidth}
onChange={updateFormValue(country)}
onSelect={onCountrySelect}
onBlur={onCountryBlur}
options={countries}
withError={false}
selected={Boolean(selectedCountry)}
/>
<Input
value={readFormValue(region)}
labelLexic='form_region'
labelWidth={labelWidth}
onChange={onRegionOrCityChange(region)}
editIcon
maxLength={500}
withError={false}
/>
<Combobox
value={readFormValue(city)}
labelLexic='form_city'
labelWidth={labelWidth}
onChange={onRegionOrCityChange(city)}
onSelect={onCitySelect}
onBlur={onCityBlur}
options={cities}
selected={Boolean(readFormValue(cityId))}
maxLength={500}
withError={false}
/>
<Input
value={readFormValue(address1)}
labelLexic='form_address1'
labelWidth={labelWidth}
autoComplete='address-line1'
onChange={updateFormValue(address1)}
editIcon
maxLength={500}
withError={false}
/>
<Input
value={readFormValue(address2)}
labelLexic='form_address2'
labelWidth={labelWidth}
autoComplete='address-line2'
onChange={updateFormValue(address2)}
editIcon
maxLength={500}
withError={false}
/>
<ButtonWrapper>
<SolidButton
disabled={!hasChanges()}
type='button'
onClick={handleSubmit}
>
<T9n t='save_changes' />
</SolidButton>
<Error t={readFormError(formError) || ''} />
</ButtonWrapper>
</Form>
)
}

@ -4,7 +4,6 @@ import { PAGES } from 'config'
import { userAccountLexics } from 'config/lexics/userAccount'
import { useLexicsConfig } from 'features/LexicsStore'
import { FormStore } from 'features/FormStore'
import { Logo } from 'features/Logo'
import { PagePersonalInfo } from './components/PagePersonalInfo'
@ -47,20 +46,18 @@ const UserAccount = () => {
</Navigations>
</Aside>
<ContentWrapper>
<FormStore>
<Route path={`${PAGES.useraccount}/personal-info`}>
<PagePersonalInfo />
</Route>
<Route path={`${PAGES.useraccount}/bank-cards`}>
<PageBankCards />
</Route>
<Route path={`${PAGES.useraccount}/subscriptions`}>
<PageSubscriptions />
</Route>
<Route path={`${PAGES.useraccount}/payment-history`}>
<PagePaymentsHistory />
</Route>
</FormStore>
<Route path={`${PAGES.useraccount}/personal-info`}>
<PagePersonalInfo />
</Route>
<Route path={`${PAGES.useraccount}/bank-cards`}>
<PageBankCards />
</Route>
<Route path={`${PAGES.useraccount}/subscriptions`}>
<PageSubscriptions />
</Route>
<Route path={`${PAGES.useraccount}/payment-history`}>
<PagePaymentsHistory />
</Route>
</ContentWrapper>
</UserAccountWrapper>
)

@ -3,10 +3,26 @@ import {
PROCEDURES,
} from 'config'
import { callApi } from 'helpers'
import type { UserInfo } from 'requests/saveUserInfo'
const proc = PROCEDURES.get_user_info
export type UserInfo = {
address_line1: string | null,
address_line2: string | null,
city: string | null,
cityId: number | null,
country?: {
id: number,
name_eng: string,
name_rus: string,
},
firstname: string | null,
lastname: string | null,
password: string | null,
phone: string | null,
region: string | null,
}
export const getUserInfo = (): Promise<UserInfo> => {
const config = {
body: { params: {}, proc },

@ -3,11 +3,10 @@ import {
PROCEDURES,
} from 'config'
import { callApi } from 'helpers'
import omit from 'lodash/omit'
const proc = PROCEDURES.save_user_info
export type UserInfo = {
export type SaveUserInfo = {
address_line1: string | null,
address_line2: string | null,
city: string | null,
@ -43,8 +42,8 @@ export const saveUserInfo = async ({
phone,
postalCode,
region,
}: UserInfo) => {
const commonConfig = {
}: SaveUserInfo) => {
const config = {
body: {
params: {
_p_address_line1: address_line1,
@ -62,9 +61,7 @@ export const saveUserInfo = async ({
proc,
},
}
const config = cityId === null
? omit(commonConfig, 'body.params._p_city_id')
: omit(commonConfig, 'body.params._p_city')
const response: Response = await callApi({
config,
url: DATA_URL,

Loading…
Cancel
Save