mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-11-30 10:42:34 +05:30
#26: email resend count down for forgot-password
This commit is contained in:
parent
291a498f19
commit
4eaefd1d9b
@ -13,7 +13,10 @@ export default class BaseAuthBody extends Component {
|
|||||||
resolve: PropTypes.func.isRequired,
|
resolve: PropTypes.func.isRequired,
|
||||||
requestRedraw: PropTypes.func.isRequired,
|
requestRedraw: PropTypes.func.isRequired,
|
||||||
auth: PropTypes.shape({
|
auth: PropTypes.shape({
|
||||||
error: PropTypes.string,
|
error: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
|
||||||
|
type: PropTypes.string,
|
||||||
|
payload: PropTypes.object
|
||||||
|
})]),
|
||||||
scopes: PropTypes.array
|
scopes: PropTypes.array
|
||||||
}),
|
}),
|
||||||
user: userShape
|
user: userShape
|
||||||
@ -22,7 +25,7 @@ export default class BaseAuthBody extends Component {
|
|||||||
renderErrors() {
|
renderErrors() {
|
||||||
return this.context.auth.error
|
return this.context.auth.error
|
||||||
? <AuthError error={this.context.auth.error} onClose={this.onClearErrors} />
|
? <AuthError error={this.context.auth.error} onClose={this.onClearErrors} />
|
||||||
: ''
|
: null
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,10 @@ class PanelTransition extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
// context props
|
// context props
|
||||||
auth: PropTypes.shape({
|
auth: PropTypes.shape({
|
||||||
error: PropTypes.string,
|
error: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
|
||||||
|
type: PropTypes.string,
|
||||||
|
payload: PropTypes.object
|
||||||
|
})]),
|
||||||
isLoading: PropTypes.bool,
|
isLoading: PropTypes.bool,
|
||||||
login: PropTypes.shape({
|
login: PropTypes.shape({
|
||||||
login: PropTypes.string,
|
login: PropTypes.string,
|
||||||
@ -82,7 +85,10 @@ class PanelTransition extends Component {
|
|||||||
|
|
||||||
static childContextTypes = {
|
static childContextTypes = {
|
||||||
auth: PropTypes.shape({
|
auth: PropTypes.shape({
|
||||||
error: PropTypes.string,
|
error: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
|
||||||
|
type: PropTypes.string,
|
||||||
|
payload: PropTypes.object
|
||||||
|
})]),
|
||||||
login: PropTypes.shape({
|
login: PropTypes.shape({
|
||||||
login: PropTypes.string,
|
login: PropTypes.string,
|
||||||
password: PropTypes.string
|
password: PropTypes.string
|
||||||
|
@ -335,7 +335,14 @@ function needActivation() {
|
|||||||
function validationErrorsHandler(dispatch) {
|
function validationErrorsHandler(dispatch) {
|
||||||
return (resp) => {
|
return (resp) => {
|
||||||
if (resp.errors) {
|
if (resp.errors) {
|
||||||
const errorMessage = resp.errors[Object.keys(resp.errors)[0]];
|
let errorMessage = resp.errors[Object.keys(resp.errors)[0]];
|
||||||
|
if (resp.data) {
|
||||||
|
errorMessage = {
|
||||||
|
type: errorMessage,
|
||||||
|
payload: resp.data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(setError(errorMessage));
|
dispatch(setError(errorMessage));
|
||||||
return Promise.reject(errorMessage);
|
return Promise.reject(errorMessage);
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,30 @@ import React, { PropTypes } from 'react';
|
|||||||
import errorsDict from 'services/errorsDict';
|
import errorsDict from 'services/errorsDict';
|
||||||
import { PanelBodyHeader } from 'components/ui/Panel';
|
import { PanelBodyHeader } from 'components/ui/Panel';
|
||||||
|
|
||||||
|
let autoHideTimer;
|
||||||
|
function resetTimer() {
|
||||||
|
if (autoHideTimer) {
|
||||||
|
clearTimeout(autoHideTimer);
|
||||||
|
autoHideTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
export default function AuthError({error, onClose = function() {}}) {
|
export default function AuthError({error, onClose = function() {}}) {
|
||||||
|
resetTimer();
|
||||||
|
|
||||||
|
if (error.type === 'error.email_frequency') {
|
||||||
|
if (error.payload && error.payload.canRepeatIn) {
|
||||||
|
error.payload.msLeft = error.payload.canRepeatIn * 1000;
|
||||||
|
setTimeout(onClose, error.payload.msLeft - Date.now() + 1500); // 1500 to let the user see, that time is elapsed
|
||||||
|
} else {
|
||||||
|
// TODO: it would be greate to log this case, when we will setup frontend logging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PanelBodyHeader type="error" onClose={onClose}>
|
<PanelBodyHeader type="error" onClose={() => {
|
||||||
|
resetTimer();
|
||||||
|
onClose();
|
||||||
|
}}>
|
||||||
{errorsDict.resolve(error)}
|
{errorsDict.resolve(error)}
|
||||||
</PanelBodyHeader>
|
</PanelBodyHeader>
|
||||||
);
|
);
|
||||||
@ -13,6 +34,9 @@ export default function AuthError({error, onClose = function() {}}) {
|
|||||||
|
|
||||||
AuthError.displayName = 'AuthError';
|
AuthError.displayName = 'AuthError';
|
||||||
AuthError.propTypes = {
|
AuthError.propTypes = {
|
||||||
error: PropTypes.string.isRequired,
|
error: PropTypes.oneOfType([PropTypes.string, PropTypes.shape({
|
||||||
|
type: PropTypes.string,
|
||||||
|
payload: PropTypes.object
|
||||||
|
})]).isRequired,
|
||||||
onClose: PropTypes.func
|
onClose: PropTypes.func
|
||||||
};
|
};
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
"components.userbar.register": "Join",
|
"components.userbar.register": "Join",
|
||||||
"pages.root.siteName": "Ely.by",
|
"pages.root.siteName": "Ely.by",
|
||||||
"services.accountNotActivated": "The account is not activated",
|
"services.accountNotActivated": "The account is not activated",
|
||||||
"services.emailFrequency": "Please cool down, you are requesting emails too often. New key can be retrieved after 30 minutes from the previous request.",
|
"services.emailFrequency": "Please cool down, you are requesting emails too often. New key can be retrieved {time}.",
|
||||||
"services.emailInvalid": "Email is invalid",
|
"services.emailInvalid": "Email is invalid",
|
||||||
"services.emailIsTempmail": "Tempmail E-mail addresses is not allowed",
|
"services.emailIsTempmail": "Tempmail E-mail addresses is not allowed",
|
||||||
"services.emailNotAvailable": "This email is already registered.",
|
"services.emailNotAvailable": "This email is already registered.",
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
"components.userbar.register": "Регистрация",
|
"components.userbar.register": "Регистрация",
|
||||||
"pages.root.siteName": "Ely.by",
|
"pages.root.siteName": "Ely.by",
|
||||||
"services.accountNotActivated": "Аккаунт не активирован",
|
"services.accountNotActivated": "Аккаунт не активирован",
|
||||||
"services.emailFrequency": "Пожалуйста, успокойтесь, вы запрашиваете E-mail слишком часто. Новый ключ можно будет заказать через 30 минут от предыдущего запроса.",
|
"services.emailFrequency": "Пожалуйста, успокойтесь, вы запрашиваете E-mail слишком часто. Новый ключ можно будет заказать {time}.",
|
||||||
"services.emailInvalid": "Указан неправильный E-mail",
|
"services.emailInvalid": "Указан неправильный E-mail",
|
||||||
"services.emailIsTempmail": "Использование сервисов временных E-mail адресов запрещено",
|
"services.emailIsTempmail": "Использование сервисов временных E-mail адресов запрещено",
|
||||||
"services.emailNotAvailable": "На указанный E-mail адрес уже зарегистрирован аккаунт.",
|
"services.emailNotAvailable": "На указанный E-mail адрес уже зарегистрирован аккаунт.",
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
"rulesAgreementRequired": "You must accept rules in order to create an account",
|
"rulesAgreementRequired": "You must accept rules in order to create an account",
|
||||||
"keyRequired": "Please, enter an activation key",
|
"keyRequired": "Please, enter an activation key",
|
||||||
"keyNotExists": "The key is incorrect",
|
"keyNotExists": "The key is incorrect",
|
||||||
"emailFrequency": "Please cool down, you are requesting emails too often. New key can be retrieved after 30 minutes from the previous request.",
|
"emailFrequency": "Please cool down, you are requesting emails too often. New key can be retrieved {time}.",
|
||||||
"accountNotActivated": "The account is not activated",
|
"accountNotActivated": "The account is not activated",
|
||||||
"oldHashStrategy": "Sorry, but your account's password is too old. Please change your password in order to perform this action."
|
"oldHashStrategy": "Sorry, but your account's password is too old. Please change your password in order to perform this action."
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { FormattedMessage as Message } from 'react-intl';
|
import { FormattedMessage as Message, FormattedRelative as Relative } from 'react-intl';
|
||||||
|
|
||||||
import messages from './errorsDict.intl.json';
|
import messages from './errorsDict.intl.json';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
resolve(error) {
|
resolve(error) {
|
||||||
return errorsMap[error] ? errorsMap[error]() : error;
|
let payload = {};
|
||||||
|
|
||||||
|
if (error.type) {
|
||||||
|
payload = error.payload;
|
||||||
|
error = error.type;
|
||||||
|
}
|
||||||
|
return errorsMap[error] ? errorsMap[error](payload) : error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,5 +76,7 @@ const errorsMap = {
|
|||||||
|
|
||||||
'error.account_not_activated': () => <Message {...messages.accountNotActivated} />,
|
'error.account_not_activated': () => <Message {...messages.accountNotActivated} />,
|
||||||
|
|
||||||
'error.email_frequency': () => <Message {...messages.emailFrequency} />
|
'error.email_frequency': (props) => <Message {...messages.emailFrequency} values={{
|
||||||
|
time: <Relative value={props.msLeft} updateInterval={1000} />
|
||||||
|
}} />
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user