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.active.username} +
+ {accounts.active.username} +
+
+ {accounts.active.email} +
+ + + + + +
-
- {accounts.active.email} -
- - Перейти в профиль Ely.by - - - Выйти -
-
- {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':