2020-04-08 21:12:58 +05:00
|
|
|
import React, { useCallback } from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { useTranslation } from 'react-i18next';
|
2022-07-26 12:26:42 +02:00
|
|
|
import { Button, Divider, Dropdown, Header, Tab } from 'semantic-ui-react';
|
2020-04-08 21:12:58 +05:00
|
|
|
|
2022-07-26 12:26:42 +02:00
|
|
|
import locales from '../../../locales';
|
2020-08-04 01:32:46 +05:00
|
|
|
import AvatarEditPopup from './AvatarEditPopup';
|
2020-04-08 21:12:58 +05:00
|
|
|
import User from '../../User';
|
2022-06-15 14:13:22 +02:00
|
|
|
import UserInformationEdit from '../../UserInformationEdit';
|
|
|
|
import UserUsernameEditPopup from '../../UserUsernameEditPopup';
|
|
|
|
import UserEmailEditPopup from '../../UserEmailEditPopup';
|
|
|
|
import UserPasswordEditPopup from '../../UserPasswordEditPopup';
|
2020-04-08 21:12:58 +05:00
|
|
|
|
2020-05-29 19:31:19 +05:00
|
|
|
import styles from './AccountPane.module.scss';
|
2020-04-08 21:12:58 +05:00
|
|
|
|
|
|
|
const AccountPane = React.memo(
|
|
|
|
({
|
|
|
|
email,
|
|
|
|
name,
|
|
|
|
username,
|
2020-04-21 05:04:34 +05:00
|
|
|
avatarUrl,
|
2020-04-09 18:27:28 +05:00
|
|
|
phone,
|
|
|
|
organization,
|
2022-07-26 12:26:42 +02:00
|
|
|
language,
|
2020-04-21 05:04:34 +05:00
|
|
|
isAvatarUpdating,
|
2020-04-08 21:12:58 +05:00
|
|
|
usernameUpdateForm,
|
|
|
|
emailUpdateForm,
|
|
|
|
passwordUpdateForm,
|
|
|
|
onUpdate,
|
2020-04-21 05:04:34 +05:00
|
|
|
onAvatarUpdate,
|
2022-07-26 12:26:42 +02:00
|
|
|
onLanguageUpdate,
|
2020-04-08 21:12:58 +05:00
|
|
|
onUsernameUpdate,
|
|
|
|
onUsernameUpdateMessageDismiss,
|
|
|
|
onEmailUpdate,
|
|
|
|
onEmailUpdateMessageDismiss,
|
|
|
|
onPasswordUpdate,
|
|
|
|
onPasswordUpdateMessageDismiss,
|
|
|
|
}) => {
|
|
|
|
const [t] = useTranslation();
|
|
|
|
|
|
|
|
const handleAvatarDelete = useCallback(() => {
|
|
|
|
onUpdate({
|
2020-04-21 05:04:34 +05:00
|
|
|
avatarUrl: null,
|
2020-04-08 21:12:58 +05:00
|
|
|
});
|
|
|
|
}, [onUpdate]);
|
|
|
|
|
2022-07-26 12:26:42 +02:00
|
|
|
const handleLanguageChange = useCallback(
|
|
|
|
(_, { value }) => {
|
|
|
|
onLanguageUpdate(value === 'auto' ? null : value); // FIXME: hack
|
|
|
|
},
|
|
|
|
[onLanguageUpdate],
|
|
|
|
);
|
|
|
|
|
2020-04-08 21:12:58 +05:00
|
|
|
return (
|
|
|
|
<Tab.Pane attached={false} className={styles.wrapper}>
|
2020-08-04 01:32:46 +05:00
|
|
|
<AvatarEditPopup
|
2020-04-21 05:04:34 +05:00
|
|
|
defaultValue={avatarUrl}
|
|
|
|
onUpdate={onAvatarUpdate}
|
2020-04-08 21:12:58 +05:00
|
|
|
onDelete={handleAvatarDelete}
|
|
|
|
>
|
2020-04-21 05:04:34 +05:00
|
|
|
<User name={name} avatarUrl={avatarUrl} size="massive" isDisabled={isAvatarUpdating} />
|
2020-08-04 01:32:46 +05:00
|
|
|
</AvatarEditPopup>
|
2020-04-08 21:12:58 +05:00
|
|
|
<br />
|
|
|
|
<br />
|
2022-06-15 14:13:22 +02:00
|
|
|
<UserInformationEdit
|
2020-04-08 21:12:58 +05:00
|
|
|
defaultData={{
|
|
|
|
name,
|
2020-04-09 18:27:28 +05:00
|
|
|
phone,
|
|
|
|
organization,
|
2020-04-08 21:12:58 +05:00
|
|
|
}}
|
|
|
|
onUpdate={onUpdate}
|
|
|
|
/>
|
2022-07-26 12:26:42 +02:00
|
|
|
<Divider horizontal section>
|
|
|
|
<Header as="h4">
|
|
|
|
{t('common.language', {
|
|
|
|
context: 'title',
|
|
|
|
})}
|
|
|
|
</Header>
|
|
|
|
</Divider>
|
|
|
|
<Dropdown
|
|
|
|
fluid
|
|
|
|
selection
|
|
|
|
options={[
|
|
|
|
{
|
|
|
|
key: 'auto',
|
|
|
|
value: 'auto',
|
|
|
|
text: t('common.detectAutomatically'),
|
|
|
|
},
|
|
|
|
...locales.map((locale) => ({
|
|
|
|
key: locale.language,
|
|
|
|
value: locale.language,
|
|
|
|
flag: locale.country,
|
|
|
|
text: locale.name,
|
|
|
|
})),
|
|
|
|
]}
|
|
|
|
value={language || 'auto'}
|
|
|
|
onChange={handleLanguageChange}
|
|
|
|
/>
|
2020-04-08 21:12:58 +05:00
|
|
|
<Divider horizontal section>
|
|
|
|
<Header as="h4">
|
|
|
|
{t('common.authentication', {
|
|
|
|
context: 'title',
|
|
|
|
})}
|
|
|
|
</Header>
|
|
|
|
</Divider>
|
|
|
|
<div className={styles.action}>
|
2022-06-15 14:13:22 +02:00
|
|
|
<UserUsernameEditPopup
|
|
|
|
usePasswordConfirmation
|
2020-04-08 21:12:58 +05:00
|
|
|
defaultData={usernameUpdateForm.data}
|
|
|
|
username={username}
|
|
|
|
isSubmitting={usernameUpdateForm.isSubmitting}
|
|
|
|
error={usernameUpdateForm.error}
|
|
|
|
onUpdate={onUsernameUpdate}
|
|
|
|
onMessageDismiss={onUsernameUpdateMessageDismiss}
|
|
|
|
>
|
|
|
|
<Button className={styles.actionButton}>
|
|
|
|
{t('action.editUsername', {
|
|
|
|
context: 'title',
|
|
|
|
})}
|
|
|
|
</Button>
|
2022-06-15 14:13:22 +02:00
|
|
|
</UserUsernameEditPopup>
|
2020-04-08 21:12:58 +05:00
|
|
|
</div>
|
|
|
|
<div className={styles.action}>
|
2022-06-15 14:13:22 +02:00
|
|
|
<UserEmailEditPopup
|
|
|
|
usePasswordConfirmation
|
2020-04-08 21:12:58 +05:00
|
|
|
defaultData={emailUpdateForm.data}
|
|
|
|
email={email}
|
|
|
|
isSubmitting={emailUpdateForm.isSubmitting}
|
|
|
|
error={emailUpdateForm.error}
|
|
|
|
onUpdate={onEmailUpdate}
|
|
|
|
onMessageDismiss={onEmailUpdateMessageDismiss}
|
|
|
|
>
|
|
|
|
<Button className={styles.actionButton}>
|
|
|
|
{t('action.editEmail', {
|
|
|
|
context: 'title',
|
|
|
|
})}
|
|
|
|
</Button>
|
2022-06-15 14:13:22 +02:00
|
|
|
</UserEmailEditPopup>
|
2020-04-08 21:12:58 +05:00
|
|
|
</div>
|
|
|
|
<div className={styles.action}>
|
2022-06-15 14:13:22 +02:00
|
|
|
<UserPasswordEditPopup
|
|
|
|
usePasswordConfirmation
|
2020-04-08 21:12:58 +05:00
|
|
|
defaultData={passwordUpdateForm.data}
|
|
|
|
isSubmitting={passwordUpdateForm.isSubmitting}
|
|
|
|
error={passwordUpdateForm.error}
|
|
|
|
onUpdate={onPasswordUpdate}
|
|
|
|
onMessageDismiss={onPasswordUpdateMessageDismiss}
|
|
|
|
>
|
|
|
|
<Button className={styles.actionButton}>
|
|
|
|
{t('action.editPassword', {
|
|
|
|
context: 'title',
|
|
|
|
})}
|
|
|
|
</Button>
|
2022-06-15 14:13:22 +02:00
|
|
|
</UserPasswordEditPopup>
|
2020-04-08 21:12:58 +05:00
|
|
|
</div>
|
|
|
|
</Tab.Pane>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
AccountPane.propTypes = {
|
|
|
|
email: PropTypes.string.isRequired,
|
|
|
|
name: PropTypes.string.isRequired,
|
|
|
|
username: PropTypes.string,
|
2020-04-21 05:04:34 +05:00
|
|
|
avatarUrl: PropTypes.string,
|
2020-04-09 18:27:28 +05:00
|
|
|
phone: PropTypes.string,
|
|
|
|
organization: PropTypes.string,
|
2022-07-26 12:26:42 +02:00
|
|
|
language: PropTypes.string,
|
2020-04-21 05:04:34 +05:00
|
|
|
isAvatarUpdating: PropTypes.bool.isRequired,
|
2020-04-08 21:12:58 +05:00
|
|
|
/* eslint-disable react/forbid-prop-types */
|
|
|
|
usernameUpdateForm: PropTypes.object.isRequired,
|
|
|
|
emailUpdateForm: PropTypes.object.isRequired,
|
|
|
|
passwordUpdateForm: PropTypes.object.isRequired,
|
|
|
|
/* eslint-enable react/forbid-prop-types */
|
|
|
|
onUpdate: PropTypes.func.isRequired,
|
2020-04-21 05:04:34 +05:00
|
|
|
onAvatarUpdate: PropTypes.func.isRequired,
|
2022-07-26 12:26:42 +02:00
|
|
|
onLanguageUpdate: PropTypes.func.isRequired,
|
2020-04-08 21:12:58 +05:00
|
|
|
onUsernameUpdate: PropTypes.func.isRequired,
|
|
|
|
onUsernameUpdateMessageDismiss: PropTypes.func.isRequired,
|
|
|
|
onEmailUpdate: PropTypes.func.isRequired,
|
|
|
|
onEmailUpdateMessageDismiss: PropTypes.func.isRequired,
|
|
|
|
onPasswordUpdate: PropTypes.func.isRequired,
|
|
|
|
onPasswordUpdateMessageDismiss: PropTypes.func.isRequired,
|
|
|
|
};
|
|
|
|
|
|
|
|
AccountPane.defaultProps = {
|
|
|
|
username: undefined,
|
2020-04-21 05:04:34 +05:00
|
|
|
avatarUrl: undefined,
|
2020-04-09 18:27:28 +05:00
|
|
|
phone: undefined,
|
|
|
|
organization: undefined,
|
2022-07-26 12:26:42 +02:00
|
|
|
language: undefined,
|
2020-04-08 21:12:58 +05:00
|
|
|
};
|
|
|
|
|
|
|
|
export default AccountPane;
|