Ott 168 login validation errors (#41)

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Mirlan 6 years ago committed by GitHub
parent c23e650512
commit 2bdde0a79a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      src/config/lexics/public.tsx
  2. 7
      src/features/AuthStore/hooks/useLogin.tsx
  3. 2
      src/features/Combobox/index.tsx
  4. 2
      src/features/Common/Input/index.tsx
  5. 4
      src/features/Common/Input/styled.tsx
  6. 64
      src/features/Login/hooks.tsx
  7. 38
      src/features/Login/index.tsx
  8. 14
      src/features/Register/components/RegistrationStep/hooks/useValidateForm.tsx
  9. 2
      src/features/Register/components/RegistrationStep/index.tsx
  10. 12
      src/requests/login.tsx

@ -1,8 +1,11 @@
export const publicLexics = {
error_account_blocked: 12909,
error_empty_email: 2498,
error_empty_password: 2499,
error_fill_out_required_fields: 12911,
error_fill_out_this_field: 12933,
error_invalid_email_format: 12908,
error_invalid_email_or_password: 2502,
error_select_country_first: 12910,
error_simple_password: 12940,
form_address1: 12914,

@ -19,12 +19,7 @@ export const useLogin = ({ setToken }: Args) => {
history.replace(PAGES.home)
}
const onError = (message: string) => {
// eslint-disable-next-line no-alert
window.alert(message)
}
return async ({ email, password }: LoginArgs) => (
login({ email, password }).then(onSuccess, onError)
login({ email, password }).then(onSuccess)
)
}

@ -88,7 +88,7 @@ export const Combobox = <T extends Option>(props: Props<T>) => {
</ComboboxPopoverStyled>
)}
</ComboboxStyled>
<Error>{error && <T9n t={error} />}</Error>
<Error t={error || ''} />
</Column>
)
}

@ -81,6 +81,6 @@ export const Input = ({
title={title}
/>
</InputWrapper>
<Error>{error && <T9n t={error} />}</Error>
<Error t={error || ''} />
</Column>
)

@ -2,6 +2,8 @@ import styled, { css } from 'styled-components/macro'
import isNil from 'lodash/isNil'
import { T9n } from 'features/T9n'
export type WrapperProps = {
error?: string | null,
paddingX?: number,
@ -88,7 +90,7 @@ export const Column = styled.div`
flex-direction: column;
`
export const Error = styled.span`
export const Error = styled(T9n)`
min-height: 16px;
margin-top: 5px;
font-style: normal;

@ -1,26 +1,68 @@
import type { FormEvent } from 'react'
import type { FormEvent, FocusEvent } from 'react'
import trim from 'lodash/trim'
import isEmpty from 'lodash/isEmpty'
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'
const readFormValue = (event: FormEvent<HTMLFormElement>) => (
(fieldName: string) => trim(event.currentTarget[fieldName]?.value)
)
export const useForm = () => {
export const useLoginForm = () => {
const {
readFormError,
readFormValue,
updateFormError,
updateFormValue,
} = useForm()
const { login } = useAuthStore()
const onEmailBlur = ({ target }: FocusEvent<HTMLInputElement>) => {
if (!isValidEmail(target.value)) {
updateFormError(formIds.email, 'error_invalid_email_format')
}
}
const readTrimmedValue = (fieldName: string) => trim(readFormValue(fieldName))
const validateForm = () => {
let hasError = false
const email = readTrimmedValue(formIds.email)
const password = readTrimmedValue(formIds.password)
if (isEmpty(email)) {
updateFormError(formIds.email, 'error_empty_email')
hasError = true
} else if (!isValidEmail(email)) {
updateFormError(formIds.email, 'error_invalid_email_format')
hasError = true
}
if (isEmpty(password)) {
updateFormError(formIds.password, 'error_empty_password')
hasError = true
}
return !hasError
}
const onError = (message: string) => {
updateFormError(formIds.formError, message)
}
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault()
const readFieldValue = readFormValue(event)
const email = readFieldValue(formIds.email)
const password = readFieldValue(formIds.password)
if (validateForm()) {
const email = readTrimmedValue(formIds.email)
const password = readTrimmedValue(formIds.password)
login({ email, password })
login({ email, password }).catch(onError)
}
}
return { handleSubmit }
return {
handleSubmit,
onEmailBlur,
readFormError,
readFormValue,
updateFormValue,
}
}

@ -5,10 +5,11 @@ import { PAGES } from 'config'
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 { useLexicsStore } from 'features/LexicsStore'
import { FormStore } from 'features/FormStore'
import { useForm } from './hooks'
import { useLoginForm } from './hooks'
import {
BlockTitle,
CenterBlock,
@ -19,10 +20,16 @@ import {
const labelWidth = 75
export const Login = () => {
const { handleSubmit } = useForm()
const { translate } = useLexicsStore()
const defaultMessage = translate('please_fill_out_this_field')
const LoginForm = () => {
const {
handleSubmit,
onEmailBlur,
readFormError,
readFormValue,
updateFormValue,
} = useLoginForm()
const requestError = readFormError(formIds.formError)
return (
<CenterBlock>
@ -32,21 +39,26 @@ export const Login = () => {
<T9n t='step_title_login' />
</BlockTitle>
{requestError && <Error t={requestError} />}
<Input
required
id={formIds.email}
type='email'
value={readFormValue(formIds.email)}
error={readFormError(formIds.email)}
onChange={updateFormValue(formIds.email)}
onBlur={onEmailBlur}
labelLexic='form_email'
labelWidth={labelWidth}
title={defaultMessage}
/>
<Input
required
id={formIds.password}
type='password'
value={readFormValue(formIds.password)}
error={readFormError(formIds.password)}
onChange={updateFormValue(formIds.password)}
labelLexic='form_password'
labelWidth={labelWidth}
title={defaultMessage}
/>
<ButtonsBlock>
@ -61,3 +73,9 @@ export const Login = () => {
</CenterBlock>
)
}
export const Login = () => (
<FormStore>
<LoginForm />
</FormStore>
)

@ -27,16 +27,16 @@ export const useValidateForm = () => {
(acc, fieldName) => {
if (isFieldEmpty(fieldName)) {
updateFormError(fieldName, message)
return acc + 1
return true
}
return acc
},
0,
false,
)
)
const validateForm = () => {
let errorsCount = 0
let hasError = false
const email = readTrimmedValue(formIds.email)
const password = readTrimmedValue(formIds.password)
if (allFieldsEmpty(requiredFields)) {
@ -46,16 +46,16 @@ export const useValidateForm = () => {
}
if (isFieldEmpty(formIds.email)) {
updateFormError(formIds.email, 'error_empty_email')
errorsCount++
hasError = true
} else if (!isValidEmail(email)) {
updateFormError(formIds.email, 'error_invalid_email_format')
}
if (!isValidPassword(password)) {
updateFormError(formIds.password, 'error_simple_password')
errorsCount++
hasError = true
}
errorsCount += setErrorOnEmptyFields(simpleValidationFields, 'error_fill_out_this_field')
return errorsCount === 0
hasError = setErrorOnEmptyFields(simpleValidationFields, 'error_fill_out_this_field')
return !hasError
}
return validateForm

@ -139,7 +139,7 @@ const Registration = () => {
<ButtonSolid type='submit'>
<T9n t='next' />
</ButtonSolid>
<Error><T9n t={readFormError(formIds.formError) || ''} /></Error>
<Error t={readFormError(formIds.formError) || ''} />
</ButtonsBlock>
</Form>
)

@ -15,12 +15,16 @@ const statusCodes = {
INVALID_CREDENTIALS: 3,
SUCCESS: 1,
USER_REMOVED_OR_BLOCKED: 4,
} as const
}
type StatusCodes = typeof statusCodes[keyof typeof statusCodes]
const errorMessages = {
[statusCodes.EMAIL_NOT_FOUND]: 'error_invalid_email_or_password',
[statusCodes.INVALID_CREDENTIALS]: 'error_invalid_email_or_password',
[statusCodes.USER_REMOVED_OR_BLOCKED]: 'error_account_blocked',
}
type Response = {
_p_status: StatusCodes,
_p_status: number,
}
type Args = {
@ -55,7 +59,7 @@ export const login = async ({
if (token && _p_status === statusCodes.SUCCESS) {
return Promise.resolve(token)
}
return Promise.reject(_p_status)
return Promise.reject(errorMessages[_p_status])
} catch (error) {
return Promise.reject()
}

Loading…
Cancel
Save