accounts-frontend/packages/app/pages/profile/ChangeEmailPage.tsx

98 lines
3.1 KiB
TypeScript
Raw Normal View History

2019-12-07 16:58:52 +05:30
import React from 'react';
2019-12-10 13:17:32 +05:30
import { RouteComponentProps, Redirect } from 'react-router-dom';
import { connect } from 'app/functions';
import FormModel from 'app/components/ui/form/FormModel';
2020-05-24 04:38:24 +05:30
import ChangeEmail, { ChangeEmailStep } from 'app/components/profile/changeEmail/ChangeEmail';
import { requestEmailChange, setNewEmail, confirmNewEmail } from 'app/services/api/accounts';
2019-12-12 12:56:23 +05:30
import Context from 'app/components/profile/Context';
2019-12-07 16:58:52 +05:30
interface RouteParams {
2020-05-24 04:38:24 +05:30
step: 'step1' | 'step2' | 'step3';
code: string;
2019-12-07 16:58:52 +05:30
}
2019-12-07 16:58:52 +05:30
interface Props extends RouteComponentProps<RouteParams> {
2020-05-24 04:38:24 +05:30
email: string;
2019-12-07 16:58:52 +05:30
}
2019-12-07 16:58:52 +05:30
class ChangeEmailPage extends React.Component<Props> {
2020-05-24 04:38:24 +05:30
static contextType = Context;
declare context: React.ContextType<typeof Context>;
2020-05-24 04:38:24 +05:30
render() {
const { step = 'step1', code } = this.props.match.params;
2020-05-24 04:38:24 +05:30
if (step && !/^step[123]$/.test(step)) {
// wrong param value
return <Redirect to="/404" />;
}
2020-05-24 04:38:24 +05:30
return (
<ChangeEmail
onSubmit={this.onSubmit}
email={this.props.email}
step={(Number(step.slice(-1)) - 1) as ChangeEmailStep}
onChangeStep={this.onChangeStep}
code={code}
/>
);
}
2020-05-24 04:38:24 +05:30
onChangeStep = (step: number) => {
this.props.history.push(`/profile/change-email/step${++step}`);
};
2020-05-24 04:38:24 +05:30
onSubmit = (step: number, form: FormModel): Promise<void> => {
return this.context
.onSubmit({
form,
sendData: () => {
const { userId } = this.context;
const data = form.serialize();
2020-05-24 04:38:24 +05:30
switch (step) {
case 0:
return requestEmailChange(userId, data.password).catch(handleErrors());
case 1:
return setNewEmail(userId, data.email, data.key).catch(
handleErrors('/profile/change-email'),
);
case 2:
return confirmNewEmail(userId, data.key).catch(handleErrors('/profile/change-email'));
default:
throw new Error(`Unsupported step ${step}`);
}
},
})
.then(() => {
step > 1 && this.context.goToProfile();
});
};
}
2020-05-24 04:38:24 +05:30
function handleErrors(repeatUrl?: string): <T extends { errors: Record<string, any> }>(resp: T) => Promise<T> {
return (resp) => {
if (resp.errors) {
if (resp.errors.key) {
resp.errors.key = {
type: resp.errors.key,
payload: {},
};
2020-05-24 04:38:24 +05:30
if (['error.key_not_exists', 'error.key_expire'].includes(resp.errors.key.type) && repeatUrl) {
Object.assign(resp.errors.key.payload, {
repeatUrl,
});
}
}
}
2020-05-24 04:38:24 +05:30
return Promise.reject(resp);
};
}
export default connect((state) => ({
2020-05-24 04:38:24 +05:30
email: state.user.email,
}))(ChangeEmailPage);