From a7d890aeecbd8e6e2bcb71e2faf675e67fa4731d Mon Sep 17 00:00:00 2001 From: Fedor Katurov <gotham48@gmail.com> Date: Fri, 5 Mar 2021 11:32:50 +0700 Subject: [PATCH] fixed error translation --- src/components/input/InputText/index.tsx | 7 ++++-- src/constants/errors.ts | 2 ++ src/containers/dialogs/LoginDialog/index.tsx | 8 +++++-- src/redux/auth/sagas.ts | 23 ++++++++++++++------ src/utils/hooks/useTranslatedError.ts | 17 +++++++++++++++ 5 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 src/utils/hooks/useTranslatedError.ts diff --git a/src/components/input/InputText/index.tsx b/src/components/input/InputText/index.tsx index 5495c068..1d4f4153 100644 --- a/src/components/input/InputText/index.tsx +++ b/src/components/input/InputText/index.tsx @@ -4,6 +4,7 @@ import styles from '~/styles/common/inputs.module.scss'; import { Icon } from '~/components/input/Icon'; import { IInputTextProps } from '~/redux/types'; import { LoaderCircle } from '~/components/input/LoaderCircle'; +import { useTranslatedError } from '~/utils/hooks/useTranslatedError'; const InputText: FC<IInputTextProps> = ({ wrapperClassName, @@ -36,6 +37,8 @@ const InputText: FC<IInputTextProps> = ({ const onFocus = useCallback(() => setFocused(true), []); const onBlur = useCallback(() => setFocused(false), []); + const translatedError = useTranslatedError(error); + useEffect(() => { if (onRef) onRef(inner_ref); }, [inner_ref, onRef]); @@ -86,9 +89,9 @@ const InputText: FC<IInputTextProps> = ({ </div> )} - {error && ( + {!!translatedError && ( <div className={styles.error}> - <span>{error}</span> + <span>{translatedError}</span> </div> )} diff --git a/src/constants/errors.ts b/src/constants/errors.ts index fbb68c4e..bf88f347 100644 --- a/src/constants/errors.ts +++ b/src/constants/errors.ts @@ -42,6 +42,7 @@ export const ERRORS = { CANT_RESTORE_COMMENT: 'CantRestoreComment', MESSAGE_NOT_FOUND: 'MessageNotFound', COMMENT_TOO_LONG: 'CommentTooLong', + NETWORK_ERROR: 'Network Error', }; export const ERROR_LITERAL = { @@ -89,4 +90,5 @@ export const ERROR_LITERAL = { [ERRORS.CANT_RESTORE_COMMENT]: 'Не удалось восстановить комментарий', [ERRORS.MESSAGE_NOT_FOUND]: 'Сообщение не найдено', [ERRORS.COMMENT_TOO_LONG]: 'Комментарий слишком длинный', + [ERRORS.NETWORK_ERROR]: 'Подключение не удалось', }; diff --git a/src/containers/dialogs/LoginDialog/index.tsx b/src/containers/dialogs/LoginDialog/index.tsx index 23792200..9aa7d12b 100644 --- a/src/containers/dialogs/LoginDialog/index.tsx +++ b/src/containers/dialogs/LoginDialog/index.tsx @@ -1,4 +1,4 @@ -import React, { FC, FormEvent, useCallback, useEffect, useState } from 'react'; +import React, { FC, FormEvent, useCallback, useEffect, useMemo, useState } from 'react'; import { connect } from 'react-redux'; import { DIALOGS, IDialogProps } from '~/redux/modal/constants'; import { useCloseOnEscape } from '~/utils/hooks'; @@ -18,6 +18,8 @@ import { pick } from 'ramda'; import { LoginDialogButtons } from '~/containers/dialogs/LoginDialogButtons'; import { OAUTH_EVENT_TYPES } from '~/redux/types'; import { DialogTitle } from '~/components/dialogs/DialogTitle'; +import { ERROR_LITERAL } from '~/constants/errors'; +import { useTranslatedError } from '~/utils/hooks/useTranslatedError'; const mapStateToProps = state => ({ ...pick(['error', 'is_registering'], selectAuthLogin(state)), @@ -90,12 +92,14 @@ const LoginDialogUnconnected: FC<IProps> = ({ useCloseOnEscape(onRequestClose); + const translatedError = useTranslatedError(error); + return ( <form onSubmit={onSubmit}> <div> <BetterScrollDialog width={300} - error={error} + error={translatedError} onClose={onRequestClose} footer={<LoginDialogButtons openOauthWindow={openOauthWindow} />} backdrop={<div className={styles.backdrop} />} diff --git a/src/redux/auth/sagas.ts b/src/redux/auth/sagas.ts index 8f029a01..40d8912b 100644 --- a/src/redux/auth/sagas.ts +++ b/src/redux/auth/sagas.ts @@ -349,10 +349,14 @@ function* loginWithSocial({ token }: ReturnType<typeof authLoginWithSocial>) { return; } } catch (error) { - const data = (error as AxiosError<{ needs_register: boolean }>).response?.data; + const { dialog }: ReturnType<typeof selectModal> = yield select(selectModal); + const data = (error as AxiosError<{ + needs_register: boolean; + errors: Record<'username' | 'password', string>; + }>).response?.data; // Backend asks us for account registration - if (data?.needs_register) { + if (dialog !== DIALOGS.LOGIN_SOCIAL_REGISTER && data?.needs_register) { yield put(authSetRegisterSocial({ token })); yield put(modalShowDialog(DIALOGS.LOGIN_SOCIAL_REGISTER)); return; @@ -391,11 +395,6 @@ function* authRegisterSocial({ username, password }: ReturnType<typeof authSendR password, }); - if (data?.errors) { - yield put(authSetRegisterSocialErrors(data.errors)); - return; - } - if (data.token) { yield put(authSetToken(data.token)); yield call(refreshUser); @@ -403,6 +402,16 @@ function* authRegisterSocial({ username, password }: ReturnType<typeof authSendR return; } } catch (error) { + const data = (error as AxiosError<{ + needs_register: boolean; + errors: Record<'username' | 'password', string>; + }>).response?.data; + + if (data?.errors) { + yield put(authSetRegisterSocialErrors(data.errors)); + return; + } + yield put(authSetRegisterSocial({ error: error.message })); } } diff --git a/src/utils/hooks/useTranslatedError.ts b/src/utils/hooks/useTranslatedError.ts new file mode 100644 index 00000000..22ef367f --- /dev/null +++ b/src/utils/hooks/useTranslatedError.ts @@ -0,0 +1,17 @@ +import { ERROR_LITERAL } from '~/constants/errors'; +import { has } from 'ramda'; +import { useMemo } from 'react'; + +export const useTranslatedError = (error: string | undefined) => { + return useMemo(() => { + if (!error) { + return ''; + } + + if (!has(error, ERROR_LITERAL)) { + return error; + } + + return ERROR_LITERAL[error]; + }, [error]); +};