diff --git a/src/components/accounts/AccountSwitcher.intl.json b/src/components/accounts/AccountSwitcher.intl.json
new file mode 100644
index 0000000..e2ceb9c
--- /dev/null
+++ b/src/components/accounts/AccountSwitcher.intl.json
@@ -0,0 +1,5 @@
+{
+ "addAccount": "Add account",
+ "goToEly": "Go to Ely.by profile",
+ "logout": "Log out"
+}
diff --git a/src/components/accounts/AccountSwitcher.jsx b/src/components/accounts/AccountSwitcher.jsx
index e6b3b98..0ce99fb 100644
--- a/src/components/accounts/AccountSwitcher.jsx
+++ b/src/components/accounts/AccountSwitcher.jsx
@@ -1,6 +1,12 @@
import React, { Component, PropTypes } from 'react';
+import classNames from 'classnames';
+import { FormattedMessage as Message } from 'react-intl';
+
+import { skins, SKIN_DARK } from 'components/ui';
+
import styles from './accountSwitcher.scss';
+import messages from './AccountSwitcher.intl.json';
const accounts = {
active: {id: 7, username: 'SleepWalker', email: 'danilenkos@auroraglobal.com'},
@@ -13,27 +19,65 @@ const accounts = {
};
export default class AccountSwitcher extends Component {
+ static displayName = 'AccountSwitcher';
+
+ static propTypes = {
+ accounts: PropTypes.shape({ // TODO: accounts shape
+ active: PropTypes.shape({
+ id: PropTypes.number
+ }),
+ available: PropTypes.arrayOf(PropTypes.shape({
+ id: PropTypes.number
+ }))
+ }),
+ skin: PropTypes.oneOf(skins),
+ hightLightActiveAccount: PropTypes.bool, // whether active account should be expanded and shown on the top
+ 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,
+ accounts
+ };
+
render() {
+ const { accounts, skin, allowAdd, allowLogout, highlightActiveAccount } = this.props;
+
+ let {available} = accounts;
+
+ if (highlightActiveAccount) {
+ available = available.filter((account) => account.id !== accounts.active.id);
+ }
+
return (
-
-
-
+
+ {highlightActiveAccount ? (
-
- {accounts.available.map((account) => (
+ ) : null}
+ {available.map((account) => (
@@ -44,34 +88,23 @@ export default class AccountSwitcher extends Component {
{account.email}
-
+ {allowLogout ? (
+
+ ) : (
+
+ )}
))}
-
+ {allowAdd ? (
-
+
- Добавить аккаунт
+
+ +
+
+
-
+ ) : null}
);
}
}
-/*
-import { intlShape } from 'react-intl';
-
-import messages from './LoggedInPanel.intl.json';
-
-
- static contextTypes = {
- intl: intlShape.isRequired
- };
-
- */
diff --git a/src/components/accounts/accountSwitcher.scss b/src/components/accounts/accountSwitcher.scss
index b408d2d..ccc8ee6 100644
--- a/src/components/accounts/accountSwitcher.scss
+++ b/src/components/accounts/accountSwitcher.scss
@@ -1,6 +1,17 @@
+@import '~components/ui/colors.scss';
+
.accountSwitcher {
background: #fff;
color: #444;
+ text-align: left;
+}
+
+.lightAccountSwitcher {
+ background: #fff;
+}
+
+.darkAccountSwitcher {
+ background: $black;
}
.logoutIcon {
@@ -8,3 +19,9 @@
color: #cdcdcd;
}
+
+.nextIcon {
+ composes: arrowRight from 'components/ui/icons.scss';
+
+ color: #cdcdcd;
+}
diff --git a/src/components/auth/PanelTransition.jsx b/src/components/auth/PanelTransition.jsx
index 0544005..2311515 100644
--- a/src/components/auth/PanelTransition.jsx
+++ b/src/components/auth/PanelTransition.jsx
@@ -33,7 +33,7 @@ const contexts = [
['login', 'password', 'forgotPassword', 'recoverPassword'],
['register', 'activation', 'resendActivation'],
['acceptRules'],
- ['permissions']
+ ['chooseAccount', 'permissions']
];
if (process.env.NODE_ENV !== 'production') {
diff --git a/src/components/auth/README.md b/src/components/auth/README.md
index f1447fc..7a8142a 100644
--- a/src/components/auth/README.md
+++ b/src/components/auth/README.md
@@ -2,12 +2,12 @@
To add new panel you need to:
-* add new state to `services/authFlow` and coresponding test to `tests/services/authFlow`
-* connect state to `authFlow`. Update `services/authFlow/AuthFlow.test` and `services/authFlow/AuthFlow.functional.test` (the last one for some complex flow)
-* add new actions to `components/auth/actions` and api endpoints to `services/api`
* create panel component at `components/auth/[panelId]`
* add new context in `components/auth/PanelTransition`
* connect component to `routes`
+* add new state to `services/authFlow` and coresponding test to `tests/services/authFlow`
+* connect state to `authFlow`. Update `services/authFlow/AuthFlow.test` and `services/authFlow/AuthFlow.functional.test` (the last one for some complex flow)
+* add new actions to `components/auth/actions` and api endpoints to `services/api`
* whatever else you need
Commit id with example: f4d315c
diff --git a/src/components/auth/chooseAccount/ChooseAccount.intl.json b/src/components/auth/chooseAccount/ChooseAccount.intl.json
new file mode 100644
index 0000000..c32f22c
--- /dev/null
+++ b/src/components/auth/chooseAccount/ChooseAccount.intl.json
@@ -0,0 +1,5 @@
+{
+ "chooseAccountTitle": "Choose an account",
+ "addAccount": "Log into another account",
+ "description": "You have logged in into multiple accounts. Please choose the one, you want to use to authorize {appName}"
+}
diff --git a/src/components/auth/chooseAccount/ChooseAccount.jsx b/src/components/auth/chooseAccount/ChooseAccount.jsx
new file mode 100644
index 0000000..1c95553
--- /dev/null
+++ b/src/components/auth/chooseAccount/ChooseAccount.jsx
@@ -0,0 +1,12 @@
+import factory from 'components/auth/factory';
+import messages from './ChooseAccount.intl.json';
+import Body from './ChooseAccountBody';
+
+export default factory({
+ title: messages.chooseAccountTitle,
+ body: Body,
+ footer: {
+ label: messages.addAccount
+ }
+});
+
diff --git a/src/components/auth/chooseAccount/ChooseAccountBody.jsx b/src/components/auth/chooseAccount/ChooseAccountBody.jsx
new file mode 100644
index 0000000..53415dd
--- /dev/null
+++ b/src/components/auth/chooseAccount/ChooseAccountBody.jsx
@@ -0,0 +1,36 @@
+import React from 'react';
+
+import { FormattedMessage as Message } from 'react-intl';
+
+import BaseAuthBody from 'components/auth/BaseAuthBody';
+import { AccountSwitcher } from 'components/accounts';
+
+import styles from './chooseAccount.scss';
+import messages from './ChooseAccount.intl.json';
+
+export default class ChooseAccountBody extends BaseAuthBody {
+ static displayName = 'ChooseAccountBody';
+ static panelId = 'chooseAccount';
+
+ render() {
+ const {user} = this.context;
+ this.context.auth.client = {name: 'foo'}; // TODO: remove me
+ const {client} = this.context.auth;
+
+ return (
+
+ {this.renderErrors()}
+
+
+ {client.name}
+ }} />
+
+
+
+
+ );
+ }
+}
diff --git a/src/components/auth/chooseAccount/chooseAccount.scss b/src/components/auth/chooseAccount/chooseAccount.scss
new file mode 100644
index 0000000..7c652e5
--- /dev/null
+++ b/src/components/auth/chooseAccount/chooseAccount.scss
@@ -0,0 +1,6 @@
+.accountSwitcherContainer {
+}
+
+.appName {
+ color: #fff;
+}
diff --git a/src/components/userbar/LoggedInPanel.jsx b/src/components/userbar/LoggedInPanel.jsx
index 4f7fb39..baade00 100644
--- a/src/components/userbar/LoggedInPanel.jsx
+++ b/src/components/userbar/LoggedInPanel.jsx
@@ -1,4 +1,4 @@
-import React, { Component, PropTypes } from 'react';
+import React, { Component } from 'react';
import classNames from 'classnames';
@@ -12,8 +12,7 @@ import { userShape } from 'components/user/User';
export default class LoggedInPanel extends Component {
static displayName = 'LoggedInPanel';
static propTypes = {
- user: userShape,
- onLogout: PropTypes.func.isRequired
+ user: userShape
};
render() {
@@ -28,16 +27,10 @@ export default class LoggedInPanel extends Component {
);
}
-
- onLogout = (event) => {
- event.preventDefault();
-
- this.props.onLogout();
- };
}
diff --git a/src/pages/root/RootPage.jsx b/src/pages/root/RootPage.jsx
index 0f6beec..a335f5d 100644
--- a/src/pages/root/RootPage.jsx
+++ b/src/pages/root/RootPage.jsx
@@ -36,7 +36,6 @@ function RootPage(props) {
@@ -58,16 +57,12 @@ RootPage.propTypes = {
pathname: PropTypes.string
}).isRequired,
children: PropTypes.element,
- logout: PropTypes.func.isRequired,
isPopupActive: PropTypes.bool.isRequired
};
import { connect } from 'react-redux';
-import { logout } from 'components/user/actions';
export default connect((state) => ({
user: state.user,
isPopupActive: state.popup.popups.length > 0
-}), {
- logout
-})(RootPage);
+}))(RootPage);
diff --git a/src/routes.js b/src/routes.js
index b61ed33..b71b57f 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -17,6 +17,7 @@ import OAuthInit from 'components/auth/OAuthInit';
import Register from 'components/auth/register/Register';
import Login from 'components/auth/login/Login';
import Permissions from 'components/auth/permissions/Permissions';
+import ChooseAccount from 'components/auth/chooseAccount/ChooseAccount';
import Activation from 'components/auth/activation/Activation';
import ResendActivation from 'components/auth/resendActivation/ResendActivation';
import Password from 'components/auth/password/Password';
@@ -62,6 +63,7 @@ export default function routesFactory(store) {
+
diff --git a/src/services/authFlow/AuthFlow.js b/src/services/authFlow/AuthFlow.js
index f23779a..a305a4d 100644
--- a/src/services/authFlow/AuthFlow.js
+++ b/src/services/authFlow/AuthFlow.js
@@ -152,6 +152,8 @@ export default class AuthFlow {
this.setState(new ResendActivationState());
break;
+ case '/oauth/choose-account':
+ break;
case '/':
case '/login':
case '/password':