bigbuffet-rw/app/soapbox/features/edit-password/index.tsx

114 lines
4.3 KiB
TypeScript
Raw Normal View History

import React from 'react';
2022-03-21 11:09:01 -07:00
import { defineMessages, useIntl } from 'react-intl';
import { changePassword } from 'soapbox/actions/security';
import snackbar from 'soapbox/actions/snackbar';
import { Button, Card, CardBody, CardHeader, CardTitle, Column, Form, FormActions, FormGroup, Input } from 'soapbox/components/ui';
2022-06-09 12:51:50 -07:00
import { useAppDispatch, useFeatures } from 'soapbox/hooks';
import PasswordIndicator from '../verification/components/password-indicator';
2022-03-21 11:09:01 -07:00
const messages = defineMessages({
updatePasswordSuccess: { id: 'security.update_password.success', defaultMessage: 'Password successfully updated.' },
updatePasswordFail: { id: 'security.update_password.fail', defaultMessage: 'Update password failed.' },
oldPasswordFieldLabel: { id: 'security.fields.old_password.label', defaultMessage: 'Current password' },
newPasswordFieldLabel: { id: 'security.fields.new_password.label', defaultMessage: 'New password' },
confirmationFieldLabel: { id: 'security.fields.password_confirmation.label', defaultMessage: 'New password (again)' },
header: { id: 'edit_password.header', defaultMessage: 'Change Password' },
submit: { id: 'security.submit', defaultMessage: 'Save changes' },
cancel: { id: 'common.cancel', defaultMessage: 'Cancel' },
});
const initialState = { currentPassword: '', newPassword: '', newPasswordConfirmation: '' };
const EditPassword = () => {
const intl = useIntl();
const dispatch = useAppDispatch();
2022-06-09 12:51:50 -07:00
const { passwordRequirements } = useFeatures();
2022-03-21 11:09:01 -07:00
const [state, setState] = React.useState(initialState);
const [isLoading, setLoading] = React.useState(false);
2022-06-09 12:51:50 -07:00
const [hasValidPassword, setHasValidPassword] = React.useState<boolean>(passwordRequirements ? false : true);
2022-03-21 11:09:01 -07:00
const { currentPassword, newPassword, newPasswordConfirmation } = state;
const resetState = () => setState(initialState);
const handleInputChange = React.useCallback((event) => {
event.persist();
setState((prevState) => ({ ...prevState, [event.target.name]: event.target.value }));
}, []);
const handleSubmit = React.useCallback(() => {
setLoading(true);
dispatch(changePassword(currentPassword, newPassword, newPasswordConfirmation)).then(() => {
resetState();
dispatch(snackbar.success(intl.formatMessage(messages.updatePasswordSuccess)));
}).finally(() => {
setLoading(false);
}).catch(() => {
resetState();
dispatch(snackbar.error(intl.formatMessage(messages.updatePasswordFail)));
});
}, [currentPassword, newPassword, newPasswordConfirmation, dispatch, intl]);
return (
<Column label={intl.formatMessage(messages.header)} transparent withHeader={false}>
<Card variant='rounded'>
<CardHeader backHref='/settings'>
<CardTitle title={intl.formatMessage(messages.header)} />
</CardHeader>
<CardBody>
<Form onSubmit={handleSubmit}>
2022-03-21 11:09:01 -07:00
<FormGroup labelText={intl.formatMessage(messages.oldPasswordFieldLabel)}>
<Input
type='password'
name='currentPassword'
onChange={handleInputChange}
value={currentPassword}
/>
</FormGroup>
<FormGroup labelText={intl.formatMessage(messages.newPasswordFieldLabel)}>
<Input
type='password'
name='newPassword'
onChange={handleInputChange}
value={newPassword}
/>
2022-06-09 12:51:50 -07:00
{passwordRequirements && (
<PasswordIndicator password={newPassword} onChange={setHasValidPassword} />
)}
2022-03-21 11:09:01 -07:00
</FormGroup>
<FormGroup labelText={intl.formatMessage(messages.confirmationFieldLabel)}>
<Input
type='password'
name='newPasswordConfirmation'
onChange={handleInputChange}
value={newPasswordConfirmation}
/>
</FormGroup>
<FormActions>
<Button to='/settings' theme='tertiary'>
2022-03-21 11:09:01 -07:00
{intl.formatMessage(messages.cancel)}
</Button>
2022-06-09 12:51:50 -07:00
<Button type='submit' theme='primary' disabled={isLoading || !hasValidPassword}>
2022-03-21 11:09:01 -07:00
{intl.formatMessage(messages.submit)}
</Button>
</FormActions>
</Form>
</CardBody>
</Card>
</Column>
);
};
export default EditPassword;