2017-08-22 21:49:50 +03:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import React, { Component } from 'react';
|
2018-02-27 23:17:31 +02:00
|
|
|
import { connect } from 'react-redux';
|
2016-11-05 22:23:56 +02:00
|
|
|
import classNames from 'classnames';
|
2017-05-25 22:11:57 +03:00
|
|
|
import { Link } from 'react-router-dom';
|
2016-11-05 22:23:56 +02:00
|
|
|
import { FormattedMessage as Message } from 'react-intl';
|
2016-11-19 11:34:19 +02:00
|
|
|
import loader from 'services/loader';
|
2016-11-08 08:07:04 +02:00
|
|
|
import { skins, SKIN_DARK, COLOR_WHITE } from 'components/ui';
|
2016-11-06 17:19:52 +03:00
|
|
|
import { Button } from 'components/ui/form';
|
2018-02-27 23:17:31 +02:00
|
|
|
import { authenticate, revoke } from 'components/accounts/actions';
|
|
|
|
import { getActiveAccount } from 'components/accounts/reducer';
|
2016-11-05 22:23:56 +02:00
|
|
|
|
2016-11-05 12:57:01 +02:00
|
|
|
import styles from './accountSwitcher.scss';
|
2016-11-05 22:23:56 +02:00
|
|
|
import messages from './AccountSwitcher.intl.json';
|
2016-11-05 12:57:01 +02:00
|
|
|
|
2016-11-12 22:31:44 +02:00
|
|
|
export class AccountSwitcher extends Component {
|
2016-11-05 22:23:56 +02:00
|
|
|
static displayName = 'AccountSwitcher';
|
|
|
|
|
|
|
|
static propTypes = {
|
2016-11-12 22:31:44 +02:00
|
|
|
switchAccount: PropTypes.func.isRequired,
|
|
|
|
removeAccount: PropTypes.func.isRequired,
|
|
|
|
onAfterAction: PropTypes.func, // called after each action performed
|
2016-11-13 16:47:56 +02:00
|
|
|
onSwitch: PropTypes.func, // called after switching an account. The active account will be passed as arg
|
2017-12-30 21:04:31 +02:00
|
|
|
accounts: PropTypes.object, // eslint-disable-line
|
2016-11-05 22:23:56 +02:00
|
|
|
skin: PropTypes.oneOf(skins),
|
2016-11-06 17:19:52 +03:00
|
|
|
highlightActiveAccount: PropTypes.bool, // whether active account should be expanded and shown on the top
|
2016-11-05 22:23:56 +02:00
|
|
|
allowLogout: PropTypes.bool, // whether to show logout icon near each account
|
|
|
|
allowAdd: PropTypes.bool // whether to show add account button
|
|
|
|
};
|
|
|
|
|
|
|
|
static defaultProps = {
|
|
|
|
skin: SKIN_DARK,
|
|
|
|
highlightActiveAccount: true,
|
|
|
|
allowLogout: true,
|
|
|
|
allowAdd: true,
|
2016-11-13 16:47:56 +02:00
|
|
|
onAfterAction() {},
|
|
|
|
onSwitch() {}
|
2016-11-05 22:23:56 +02:00
|
|
|
};
|
|
|
|
|
2016-11-05 12:57:01 +02:00
|
|
|
render() {
|
2016-11-05 22:23:56 +02:00
|
|
|
const { accounts, skin, allowAdd, allowLogout, highlightActiveAccount } = this.props;
|
2018-02-27 23:17:31 +02:00
|
|
|
const activeAccount = getActiveAccount({ accounts });
|
2016-11-05 22:23:56 +02:00
|
|
|
|
|
|
|
let {available} = accounts;
|
|
|
|
|
|
|
|
if (highlightActiveAccount) {
|
2016-11-19 17:46:55 +02:00
|
|
|
available = available.filter((account) => account.id !== activeAccount.id);
|
2016-11-05 22:23:56 +02:00
|
|
|
}
|
|
|
|
|
2016-11-05 12:57:01 +02:00
|
|
|
return (
|
2016-11-05 22:23:56 +02:00
|
|
|
<div className={classNames(
|
|
|
|
styles.accountSwitcher,
|
|
|
|
styles[`${skin}AccountSwitcher`],
|
|
|
|
)}>
|
|
|
|
{highlightActiveAccount ? (
|
2016-11-06 02:35:09 +03:00
|
|
|
<div className={styles.item}>
|
2016-11-06 17:19:52 +03:00
|
|
|
<div className={classNames(
|
|
|
|
styles.accountIcon,
|
|
|
|
styles.activeAccountIcon,
|
|
|
|
styles.accountIcon1
|
2016-11-12 22:31:44 +02:00
|
|
|
)} />
|
2016-11-06 02:35:09 +03:00
|
|
|
<div className={styles.activeAccountInfo}>
|
|
|
|
<div className={styles.activeAccountUsername}>
|
2016-11-19 17:46:55 +02:00
|
|
|
{activeAccount.username}
|
2016-11-05 22:23:56 +02:00
|
|
|
</div>
|
2016-11-06 17:19:52 +03:00
|
|
|
<div className={classNames(styles.accountEmail, styles.activeAccountEmail)}>
|
2016-11-19 17:46:55 +02:00
|
|
|
{activeAccount.email}
|
2016-11-05 22:23:56 +02:00
|
|
|
</div>
|
2016-11-06 02:35:09 +03:00
|
|
|
<div className={styles.links}>
|
|
|
|
<div className={styles.link}>
|
2016-11-19 17:46:55 +02:00
|
|
|
<a href={`http://ely.by/u${activeAccount.id}`} target="_blank">
|
2016-11-06 02:35:09 +03:00
|
|
|
<Message {...messages.goToEly} />
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
<div className={styles.link}>
|
2016-11-19 17:46:55 +02:00
|
|
|
<a className={styles.link} onClick={this.onRemove(activeAccount)} href="#">
|
2016-11-06 02:35:09 +03:00
|
|
|
<Message {...messages.logout} />
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
2016-11-05 12:57:01 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
2016-11-05 22:23:56 +02:00
|
|
|
) : null}
|
2018-02-27 23:17:31 +02:00
|
|
|
{available.map((account, index) => (
|
2016-11-12 22:31:44 +02:00
|
|
|
<div className={classNames(styles.item, styles.accountSwitchItem)}
|
|
|
|
key={account.id}
|
|
|
|
onClick={this.onSwitch(account)}
|
|
|
|
>
|
2016-11-06 17:19:52 +03:00
|
|
|
<div className={classNames(
|
|
|
|
styles.accountIcon,
|
2018-02-27 23:17:31 +02:00
|
|
|
styles[`accountIcon${index % 7 + (highlightActiveAccount ? 2 : 1)}`]
|
2016-11-12 22:31:44 +02:00
|
|
|
)} />
|
2016-11-06 17:19:52 +03:00
|
|
|
|
2016-11-05 22:23:56 +02:00
|
|
|
{allowLogout ? (
|
2016-11-12 22:31:44 +02:00
|
|
|
<div className={styles.logoutIcon} onClick={this.onRemove(account)} />
|
2016-11-05 22:23:56 +02:00
|
|
|
) : (
|
2016-11-12 22:31:44 +02:00
|
|
|
<div className={styles.nextIcon} />
|
2016-11-05 22:23:56 +02:00
|
|
|
)}
|
2016-11-06 17:19:52 +03:00
|
|
|
|
|
|
|
<div className={styles.accountInfo}>
|
|
|
|
<div className={styles.accountUsername}>
|
|
|
|
{account.username}
|
|
|
|
</div>
|
|
|
|
<div className={styles.accountEmail}>
|
|
|
|
{account.email}
|
|
|
|
</div>
|
|
|
|
</div>
|
2016-11-05 12:57:01 +02:00
|
|
|
</div>
|
|
|
|
))}
|
2016-11-05 22:23:56 +02:00
|
|
|
{allowAdd ? (
|
2016-11-12 22:31:44 +02:00
|
|
|
<Link to="/login" onClick={this.props.onAfterAction}>
|
2016-11-06 17:19:52 +03:00
|
|
|
<Button
|
2016-11-08 08:07:04 +02:00
|
|
|
color={COLOR_WHITE}
|
2016-11-06 17:19:52 +03:00
|
|
|
block
|
|
|
|
small
|
|
|
|
className={styles.addAccount}
|
|
|
|
label={
|
|
|
|
<Message {...messages.addAccount}>
|
2017-06-12 22:32:59 +03:00
|
|
|
{(message) => (
|
2016-11-06 17:19:52 +03:00
|
|
|
<span>
|
|
|
|
<div className={styles.addIcon} />
|
|
|
|
{message}
|
|
|
|
</span>
|
2017-06-12 22:32:59 +03:00
|
|
|
)}
|
2016-11-06 17:19:52 +03:00
|
|
|
</Message>
|
|
|
|
}
|
|
|
|
/>
|
2016-11-11 09:39:01 +02:00
|
|
|
</Link>
|
2016-11-05 22:23:56 +02:00
|
|
|
) : null}
|
2016-11-05 12:57:01 +02:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2016-11-12 22:31:44 +02:00
|
|
|
|
|
|
|
onSwitch = (account) => (event) => {
|
|
|
|
event.preventDefault();
|
|
|
|
|
2016-11-19 11:34:19 +02:00
|
|
|
loader.show();
|
|
|
|
|
2016-11-12 22:31:44 +02:00
|
|
|
this.props.switchAccount(account)
|
2018-02-17 21:55:47 +02:00
|
|
|
.finally(() => this.props.onAfterAction())
|
2016-11-19 11:34:19 +02:00
|
|
|
.then(() => this.props.onSwitch(account))
|
2018-02-17 21:55:47 +02:00
|
|
|
// we won't sent any logs to sentry, because an error should be already
|
|
|
|
// handled by external logic
|
|
|
|
.catch((error) => console.warn('Error switching account', { error }))
|
2016-11-19 11:34:19 +02:00
|
|
|
.finally(() => loader.hide());
|
2016-11-12 22:31:44 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
onRemove = (account) => (event) => {
|
|
|
|
event.preventDefault();
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
|
|
this.props.removeAccount(account)
|
|
|
|
.then(() => this.props.onAfterAction());
|
|
|
|
};
|
2016-11-05 12:57:01 +02:00
|
|
|
}
|
|
|
|
|
2018-02-27 23:17:31 +02:00
|
|
|
export default connect(({accounts}) => ({
|
2016-11-19 12:19:15 +02:00
|
|
|
accounts,
|
2016-11-12 22:31:44 +02:00
|
|
|
}), {
|
|
|
|
switchAccount: authenticate,
|
|
|
|
removeAccount: revoke
|
|
|
|
})(AccountSwitcher);
|