mirror of
				https://github.com/elyby/accounts-frontend.git
				synced 2025-05-31 14:11:58 +05:30 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into finish-page
This commit is contained in:
		| @@ -18,11 +18,11 @@ | |||||||
|     "history": "^1.17.0", |     "history": "^1.17.0", | ||||||
|     "intl-format-cache": "^2.0.4", |     "intl-format-cache": "^2.0.4", | ||||||
|     "intl-messageformat": "^1.1.0", |     "intl-messageformat": "^1.1.0", | ||||||
|     "react": "^0.14.0", |     "react": "^15.0.0-rc.1", | ||||||
|     "react-dom": "^0.14.3", |     "react-dom": "^15.0.0-rc.1", | ||||||
|     "react-height": "^2.0.3", |     "react-height": "^2.0.3", | ||||||
|     "react-helmet": "^2.3.1", |     "react-helmet": "^2.3.1", | ||||||
|     "react-intl": "=2.0.0-beta-2", |     "react-intl": "=v2.0.0-rc-1", | ||||||
|     "react-motion": "^0.4.0", |     "react-motion": "^0.4.0", | ||||||
|     "react-redux": "^4.0.0", |     "react-redux": "^4.0.0", | ||||||
|     "react-router": "^2.0.0", |     "react-router": "^2.0.0", | ||||||
|   | |||||||
| @@ -3,30 +3,33 @@ | |||||||
|  */ |  */ | ||||||
| import React, { Component, PropTypes } from 'react'; | import React, { Component, PropTypes } from 'react'; | ||||||
|  |  | ||||||
| import AuthError from './AuthError'; | import AuthError from 'components/auth/authError/AuthError'; | ||||||
|  | import { userShape } from 'components/user/User'; | ||||||
|  |  | ||||||
| export default class BaseAuthBody extends Component { | export default class BaseAuthBody extends Component { | ||||||
|     static propTypes = { |     static contextTypes = { | ||||||
|         clearErrors: PropTypes.func.isRequired, |         clearErrors: PropTypes.func.isRequired, | ||||||
|         resolve: PropTypes.func.isRequired, |         resolve: PropTypes.func.isRequired, | ||||||
|         reject: PropTypes.func.isRequired, |         reject: PropTypes.func.isRequired, | ||||||
|         auth: PropTypes.shape({ |         auth: PropTypes.shape({ | ||||||
|             error: PropTypes.string |             error: PropTypes.string, | ||||||
|         }) |             scopes: PropTypes.array | ||||||
|  |         }), | ||||||
|  |         user: userShape | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     renderErrors() { |     renderErrors() { | ||||||
|         return this.props.auth.error |         return this.context.auth.error | ||||||
|             ? <AuthError error={this.props.auth.error} onClose={this.onClearErrors} /> |             ? <AuthError error={this.context.auth.error} onClose={this.onClearErrors} /> | ||||||
|             : '' |             : '' | ||||||
|             ; |             ; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     onFormSubmit() { |     onFormSubmit() { | ||||||
|         this.props.resolve(this.serialize()); |         this.context.resolve(this.serialize()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     onClearErrors = this.props.clearErrors; |     onClearErrors = this.context.clearErrors; | ||||||
|  |  | ||||||
|     form = {}; |     form = {}; | ||||||
|  |  | ||||||
| @@ -39,6 +42,35 @@ export default class BaseAuthBody extends Component { | |||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Fixes some issues with scroll, when input beeing focused | ||||||
|  |      * | ||||||
|  |      * When an element is focused, by default browsers will scroll its parents to display | ||||||
|  |      * focused item to user. This behavior may cause unexpected visual effects, when | ||||||
|  |      * you animating apearing of an input (e.g. transform) and auto focusing it. In | ||||||
|  |      * that case the browser will scroll the parent container so that input will be | ||||||
|  |      * visible. | ||||||
|  |      * This method will fix that issue by finding parent with overflow: hidden and | ||||||
|  |      * reseting its scrollLeft value to 0. | ||||||
|  |      * | ||||||
|  |      * Usage: | ||||||
|  |      * <input autoFocus onFocus={this.fixAutoFocus} /> | ||||||
|  |      * | ||||||
|  |      * @param {Object} event | ||||||
|  |      */ | ||||||
|  |     fixAutoFocus = (event) => { | ||||||
|  |         let el = event.target; | ||||||
|  |  | ||||||
|  |         while (el.parentNode) { | ||||||
|  |             el = el.parentNode; | ||||||
|  |  | ||||||
|  |             if (getComputedStyle(el).overflow === 'hidden') { | ||||||
|  |                 el.scrollLeft = 0; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|     serialize() { |     serialize() { | ||||||
|         return Object.keys(this.form).reduce((acc, key) => { |         return Object.keys(this.form).reduce((acc, key) => { | ||||||
|             acc[key] = this.form[key].getValue(); |             acc[key] = this.form[key].getValue(); | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ import {helpLinks as helpLinksStyles} from 'components/auth/helpLinks.scss'; | |||||||
| import panelStyles from 'components/ui/panel.scss'; | import panelStyles from 'components/ui/panel.scss'; | ||||||
| import icons from 'components/ui/icons.scss'; | import icons from 'components/ui/icons.scss'; | ||||||
| import authFlow from 'services/authFlow'; | import authFlow from 'services/authFlow'; | ||||||
|  | import { userShape } from 'components/user/User'; | ||||||
|  |  | ||||||
| import * as actions from './actions'; | import * as actions from './actions'; | ||||||
|  |  | ||||||
| @@ -21,6 +22,7 @@ class PanelTransition extends Component { | |||||||
|     static displayName = 'PanelTransition'; |     static displayName = 'PanelTransition'; | ||||||
|  |  | ||||||
|     static propTypes = { |     static propTypes = { | ||||||
|  |         // context props | ||||||
|         auth: PropTypes.shape({ |         auth: PropTypes.shape({ | ||||||
|             error: PropTypes.string, |             error: PropTypes.string, | ||||||
|             login: PropTypes.shape({ |             login: PropTypes.shape({ | ||||||
| @@ -28,8 +30,13 @@ class PanelTransition extends Component { | |||||||
|                 password: PropTypes.string |                 password: PropTypes.string | ||||||
|             }) |             }) | ||||||
|         }).isRequired, |         }).isRequired, | ||||||
|  |         user: userShape.isRequired, | ||||||
|         setError: React.PropTypes.func.isRequired, |         setError: React.PropTypes.func.isRequired, | ||||||
|         clearErrors: React.PropTypes.func.isRequired, |         clearErrors: React.PropTypes.func.isRequired, | ||||||
|  |         resolve: React.PropTypes.func.isRequired, | ||||||
|  |         reject: React.PropTypes.func.isRequired, | ||||||
|  |  | ||||||
|  |         // local props | ||||||
|         path: PropTypes.string.isRequired, |         path: PropTypes.string.isRequired, | ||||||
|         Title: PropTypes.element.isRequired, |         Title: PropTypes.element.isRequired, | ||||||
|         Body: PropTypes.element.isRequired, |         Body: PropTypes.element.isRequired, | ||||||
| @@ -37,6 +44,30 @@ class PanelTransition extends Component { | |||||||
|         Links: PropTypes.element.isRequired |         Links: PropTypes.element.isRequired | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |     static childContextTypes = { | ||||||
|  |         auth: PropTypes.shape({ | ||||||
|  |             error: PropTypes.string, | ||||||
|  |             login: PropTypes.shape({ | ||||||
|  |                 login: PropTypes.string, | ||||||
|  |                 password: PropTypes.string | ||||||
|  |             }) | ||||||
|  |         }), | ||||||
|  |         user: userShape, | ||||||
|  |         clearErrors: React.PropTypes.func, | ||||||
|  |         resolve: PropTypes.func, | ||||||
|  |         reject: PropTypes.func | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     getChildContext() { | ||||||
|  |         return { | ||||||
|  |             auth: this.props.auth, | ||||||
|  |             user: this.props.user, | ||||||
|  |             clearErrors: this.props.clearErrors, | ||||||
|  |             resolve: this.props.resolve, | ||||||
|  |             reject: this.props.reject | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     state = { |     state = { | ||||||
|         height: {}, |         height: {}, | ||||||
|         contextHeight: 0 |         contextHeight: 0 | ||||||
| @@ -91,7 +122,7 @@ class PanelTransition extends Component { | |||||||
|  |  | ||||||
|                     const contentHeight = { |                     const contentHeight = { | ||||||
|                         overflow: 'hidden', |                         overflow: 'hidden', | ||||||
|                         height: forceHeight ? common.switchContextHeightSpring : 'auto' |                         height: forceHeight ? common.style.switchContextHeightSpring : 'auto' | ||||||
|                     }; |                     }; | ||||||
|  |  | ||||||
|                     const bodyHeight = { |                     const bodyHeight = { | ||||||
| @@ -141,6 +172,7 @@ class PanelTransition extends Component { | |||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param  {Object} config |      * @param  {Object} config | ||||||
|  |      * @param  {string} config.key | ||||||
|      * @param  {Object} [options] |      * @param  {Object} [options] | ||||||
|      * @param  {Object} [options.isLeave=false] - true, if this is a leave transition |      * @param  {Object} [options.isLeave=false] - true, if this is a leave transition | ||||||
|      * |      * | ||||||
| @@ -235,7 +267,7 @@ class PanelTransition extends Component { | |||||||
|             <div key={`header${key}`} style={style}> |             <div key={`header${key}`} style={style}> | ||||||
|                 {hasBackButton ? backButton : null} |                 {hasBackButton ? backButton : null} | ||||||
|                 <div style={scrollStyle}> |                 <div style={scrollStyle}> | ||||||
|                     {React.cloneElement(Title, this.props)} |                     {Title} | ||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|         ); |         ); | ||||||
| @@ -263,7 +295,6 @@ class PanelTransition extends Component { | |||||||
|         return ( |         return ( | ||||||
|             <ReactHeight key={`body${key}`} style={style} onHeightReady={this.onUpdateHeight}> |             <ReactHeight key={`body${key}`} style={style} onHeightReady={this.onUpdateHeight}> | ||||||
|                 {React.cloneElement(Body, { |                 {React.cloneElement(Body, { | ||||||
|                     ...this.props, |  | ||||||
|                     ref: (body) => { |                     ref: (body) => { | ||||||
|                         this.body = body; |                         this.body = body; | ||||||
|                     } |                     } | ||||||
| @@ -279,7 +310,7 @@ class PanelTransition extends Component { | |||||||
|  |  | ||||||
|         return ( |         return ( | ||||||
|             <div key={`footer${key}`} style={style}> |             <div key={`footer${key}`} style={style}> | ||||||
|                 {React.cloneElement(Footer, this.props)} |                 {Footer} | ||||||
|             </div> |             </div> | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| @@ -291,15 +322,15 @@ class PanelTransition extends Component { | |||||||
|  |  | ||||||
|         return ( |         return ( | ||||||
|             <div key={`links${key}`} style={style}> |             <div key={`links${key}`} style={style}> | ||||||
|                 {React.cloneElement(Links, this.props)} |                 {Links} | ||||||
|             </div> |             </div> | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param  {string} key |      * @param  {string} key | ||||||
|      * @param  {Object} props |      * @param  {Object} style | ||||||
|      * @param  {number} props.opacitySpring |      * @param  {number} style.opacitySpring | ||||||
|      * |      * | ||||||
|      * @return {Object} |      * @return {Object} | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| import React, { PropTypes } from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| import { FormattedMessage as Message } from 'react-intl'; | import { FormattedMessage as Message } from 'react-intl'; | ||||||
| import Helmet from 'react-helmet'; | import Helmet from 'react-helmet'; | ||||||
| @@ -6,20 +6,12 @@ import Helmet from 'react-helmet'; | |||||||
| import buttons from 'components/ui/buttons.scss'; | import buttons from 'components/ui/buttons.scss'; | ||||||
| import { Input } from 'components/ui/Form'; | import { Input } from 'components/ui/Form'; | ||||||
| 
 | 
 | ||||||
| import BaseAuthBody from './BaseAuthBody'; | import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||||
| import styles from './activation.scss'; | import styles from './activation.scss'; | ||||||
| import messages from './Activation.messages'; | import messages from './Activation.messages'; | ||||||
| 
 | 
 | ||||||
| class Body extends BaseAuthBody { | class Body extends BaseAuthBody { | ||||||
|     static propTypes = { |     static displayName = 'ActivationBody'; | ||||||
|         ...BaseAuthBody.propTypes, |  | ||||||
|         auth: PropTypes.shape({ |  | ||||||
|             error: PropTypes.string, |  | ||||||
|             login: PropTypes.shape({ |  | ||||||
|                 login: PropTypes.stirng |  | ||||||
|             }) |  | ||||||
|         }) |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     render() { |     render() { | ||||||
|         return ( |         return ( | ||||||
| @@ -31,7 +23,7 @@ class Body extends BaseAuthBody { | |||||||
| 
 | 
 | ||||||
|                     <div className={styles.descriptionText}> |                     <div className={styles.descriptionText}> | ||||||
|                         <Message {...messages.activationMailWasSent} values={{ |                         <Message {...messages.activationMailWasSent} values={{ | ||||||
|                             email: (<b>{this.props.user.email}</b>) |                             email: (<b>{this.context.user.email}</b>) | ||||||
|                         }} /> |                         }} /> | ||||||
|                     </div> |                     </div> | ||||||
|                 </div> |                 </div> | ||||||
| @@ -40,6 +32,7 @@ class Body extends BaseAuthBody { | |||||||
|                         color="blue" |                         color="blue" | ||||||
|                         className={styles.activationCodeInput} |                         className={styles.activationCodeInput} | ||||||
|                         autoFocus |                         autoFocus | ||||||
|  |                         onFocus={this.fixAutoFocus} | ||||||
|                         required |                         required | ||||||
|                         placeholder={messages.enterTheCode} |                         placeholder={messages.enterTheCode} | ||||||
|                     /> |                     /> | ||||||
| @@ -11,8 +11,8 @@ export default class AppInfo extends Component { | |||||||
|     static displayName = 'AppInfo'; |     static displayName = 'AppInfo'; | ||||||
| 
 | 
 | ||||||
|     static propTypes = { |     static propTypes = { | ||||||
|         name: PropTypes.string.isRequired, |         name: PropTypes.string, | ||||||
|         description: PropTypes.string.isRequired, |         description: PropTypes.string, | ||||||
|         onGoToAuth: PropTypes.func.isRequired |         onGoToAuth: PropTypes.func.isRequired | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| import React, { PropTypes } from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| import { FormattedMessage as Message } from 'react-intl'; | import { FormattedMessage as Message } from 'react-intl'; | ||||||
| import Helmet from 'react-helmet'; | import Helmet from 'react-helmet'; | ||||||
| @@ -6,22 +6,13 @@ import Helmet from 'react-helmet'; | |||||||
| import buttons from 'components/ui/buttons.scss'; | import buttons from 'components/ui/buttons.scss'; | ||||||
| import { Input } from 'components/ui/Form'; | import { Input } from 'components/ui/Form'; | ||||||
| 
 | 
 | ||||||
| import BaseAuthBody from './BaseAuthBody'; | import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||||
| import messages from './ForgotPassword.messages'; | import messages from './ForgotPassword.messages'; | ||||||
| 
 | 
 | ||||||
| import styles from './forgotPassword.scss'; | import styles from './forgotPassword.scss'; | ||||||
| 
 | 
 | ||||||
| class Body extends BaseAuthBody { | class Body extends BaseAuthBody { | ||||||
|     static propTypes = { |     static displayName = 'ForgotPasswordBody'; | ||||||
|         ...BaseAuthBody.propTypes, |  | ||||||
|         //login: PropTypes.func.isRequired, |  | ||||||
|         auth: PropTypes.shape({ |  | ||||||
|             error: PropTypes.string, |  | ||||||
|             login: PropTypes.shape({ |  | ||||||
|                 email: PropTypes.stirng |  | ||||||
|             }) |  | ||||||
|         }) |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     // Если юзер вводил своё мыло во время попытки авторизации, то почему бы его сюда автоматически не подставить? |     // Если юзер вводил своё мыло во время попытки авторизации, то почему бы его сюда автоматически не подставить? | ||||||
|     render() { |     render() { | ||||||
| @@ -37,6 +28,7 @@ class Body extends BaseAuthBody { | |||||||
|                     icon="envelope" |                     icon="envelope" | ||||||
|                     color="lightViolet" |                     color="lightViolet" | ||||||
|                     autoFocus |                     autoFocus | ||||||
|  |                     onFocus={this.fixAutoFocus} | ||||||
|                     required |                     required | ||||||
|                     placeholder={messages.accountEmail} |                     placeholder={messages.accountEmail} | ||||||
|                 /> |                 /> | ||||||
| @@ -49,7 +41,6 @@ class Body extends BaseAuthBody { | |||||||
| 
 | 
 | ||||||
|     onFormSubmit() { |     onFormSubmit() { | ||||||
|         // TODO: обработчик отправки письма с инструкцией по смене аккаунта |         // TODO: обработчик отправки письма с инструкцией по смене аккаунта | ||||||
|         //this.props.login(this.serialize()); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| import React, { PropTypes } from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| import { FormattedMessage as Message } from 'react-intl'; | import { FormattedMessage as Message } from 'react-intl'; | ||||||
| import Helmet from 'react-helmet'; | import Helmet from 'react-helmet'; | ||||||
| @@ -7,20 +7,12 @@ import { Link } from 'react-router'; | |||||||
| import buttons from 'components/ui/buttons.scss'; | import buttons from 'components/ui/buttons.scss'; | ||||||
| import { Input } from 'components/ui/Form'; | import { Input } from 'components/ui/Form'; | ||||||
| 
 | 
 | ||||||
| import BaseAuthBody from './BaseAuthBody'; | import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||||
|  | import passwordMessages from 'components/auth/password/Password.messages'; | ||||||
| import messages from './Login.messages'; | import messages from './Login.messages'; | ||||||
| import passwordMessages from './Password.messages'; |  | ||||||
| 
 | 
 | ||||||
| class Body extends BaseAuthBody { | class Body extends BaseAuthBody { | ||||||
|     static propTypes = { |     static displayName = 'LoginBody'; | ||||||
|         ...BaseAuthBody.propTypes, |  | ||||||
|         auth: PropTypes.shape({ |  | ||||||
|             error: PropTypes.string, |  | ||||||
|             login: PropTypes.shape({ |  | ||||||
|                 login: PropTypes.stirng |  | ||||||
|             }) |  | ||||||
|         }) |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     render() { |     render() { | ||||||
|         return ( |         return ( | ||||||
| @@ -30,6 +22,7 @@ class Body extends BaseAuthBody { | |||||||
|                 <Input {...this.bindField('login')} |                 <Input {...this.bindField('login')} | ||||||
|                     icon="envelope" |                     icon="envelope" | ||||||
|                     autoFocus |                     autoFocus | ||||||
|  |                     onFocus={this.fixAutoFocus} | ||||||
|                     required |                     required | ||||||
|                     placeholder={messages.emailOrUsername} |                     placeholder={messages.emailOrUsername} | ||||||
|                 /> |                 /> | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| import React, { PropTypes } from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| import { FormattedMessage as Message } from 'react-intl'; | import { FormattedMessage as Message } from 'react-intl'; | ||||||
| import Helmet from 'react-helmet'; | import Helmet from 'react-helmet'; | ||||||
| @@ -8,24 +8,15 @@ import buttons from 'components/ui/buttons.scss'; | |||||||
| import icons from 'components/ui/icons.scss'; | import icons from 'components/ui/icons.scss'; | ||||||
| import { Input, Checkbox } from 'components/ui/Form'; | import { Input, Checkbox } from 'components/ui/Form'; | ||||||
| 
 | 
 | ||||||
| import BaseAuthBody from './BaseAuthBody'; | import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||||
| import styles from './password.scss'; | import styles from './password.scss'; | ||||||
| import messages from './Password.messages'; | import messages from './Password.messages'; | ||||||
| 
 | 
 | ||||||
| class Body extends BaseAuthBody { | class Body extends BaseAuthBody { | ||||||
|     static propTypes = { |     static displayName = 'PasswordBody'; | ||||||
|         ...BaseAuthBody.propTypes, |  | ||||||
|         auth: PropTypes.shape({ |  | ||||||
|             error: PropTypes.string, |  | ||||||
|             login: PropTypes.shape({ |  | ||||||
|                 login: PropTypes.stirng, |  | ||||||
|                 password: PropTypes.stirng |  | ||||||
|             }) |  | ||||||
|         }) |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     render() { |     render() { | ||||||
|         const {user} = this.props; |         const {user} = this.context; | ||||||
| 
 | 
 | ||||||
|         return ( |         return ( | ||||||
|             <div> |             <div> | ||||||
| @@ -46,6 +37,7 @@ class Body extends BaseAuthBody { | |||||||
|                     icon="key" |                     icon="key" | ||||||
|                     type="password" |                     type="password" | ||||||
|                     autoFocus |                     autoFocus | ||||||
|  |                     onFocus={this.fixAutoFocus} | ||||||
|                     required |                     required | ||||||
|                     placeholder={messages.accountPassword} |                     placeholder={messages.accountPassword} | ||||||
|                 /> |                 /> | ||||||
| @@ -2,21 +2,18 @@ import React, { PropTypes } from 'react'; | |||||||
| 
 | 
 | ||||||
| import { FormattedMessage as Message } from 'react-intl'; | import { FormattedMessage as Message } from 'react-intl'; | ||||||
| import Helmet from 'react-helmet'; | import Helmet from 'react-helmet'; | ||||||
| import { Link } from 'react-router'; |  | ||||||
| 
 | 
 | ||||||
| import buttons from 'components/ui/buttons.scss'; | import buttons from 'components/ui/buttons.scss'; | ||||||
| import { Input } from 'components/ui/Form'; | import { Input } from 'components/ui/Form'; | ||||||
| 
 | 
 | ||||||
| import BaseAuthBody from './BaseAuthBody'; | import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||||
| import passwordChangedMessages from './PasswordChange.messages'; | import passwordChangedMessages from './PasswordChange.messages'; | ||||||
| 
 | 
 | ||||||
| import icons from 'components/ui/icons.scss'; | import icons from 'components/ui/icons.scss'; | ||||||
| import styles from './passwordChange.scss'; | import styles from './passwordChange.scss'; | ||||||
| 
 | 
 | ||||||
| class Body extends BaseAuthBody { | class Body extends BaseAuthBody { | ||||||
|     static propTypes = { |     static displayName = 'PasswordChangeBody'; | ||||||
|         ...BaseAuthBody.propTypes |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     render() { |     render() { | ||||||
|         return ( |         return ( | ||||||
| @@ -35,6 +32,7 @@ class Body extends BaseAuthBody { | |||||||
|                     icon="key" |                     icon="key" | ||||||
|                     color="darkBlue" |                     color="darkBlue" | ||||||
|                     autoFocus |                     autoFocus | ||||||
|  |                     onFocus={this.fixAutoFocus} | ||||||
|                     required |                     required | ||||||
|                     placeholder={passwordChangedMessages.newPassword} |                     placeholder={passwordChangedMessages.newPassword} | ||||||
|                 /> |                 /> | ||||||
| @@ -51,7 +49,7 @@ class Body extends BaseAuthBody { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default function PasswordChange() { | export default function PasswordChange() { | ||||||
|     return { |     const componentsMap = { | ||||||
|         Title: () => ( // TODO: separate component for PageTitle |         Title: () => ( // TODO: separate component for PageTitle | ||||||
|             <Message {...passwordChangedMessages.changePasswordTitle}> |             <Message {...passwordChangedMessages.changePasswordTitle}> | ||||||
|                 {(msg) => <span>{msg}<Helmet title={msg} /></span>} |                 {(msg) => <span>{msg}<Helmet title={msg} /></span>} | ||||||
| @@ -63,14 +61,20 @@ export default function PasswordChange() { | |||||||
|                 <Message {...passwordChangedMessages.change} /> |                 <Message {...passwordChangedMessages.change} /> | ||||||
|             </button> |             </button> | ||||||
|         ), |         ), | ||||||
|         Links: (props) => ( |         Links: (props, context) => ( | ||||||
|             <a href="#" onClick={(event) => { |             <a href="#" onClick={(event) => { | ||||||
|                 event.preventDefault(); |                 event.preventDefault(); | ||||||
| 
 | 
 | ||||||
|                 props.reject(); |                 context.reject(); | ||||||
|             }}> |             }}> | ||||||
|                 <Message {...passwordChangedMessages.skipThisStep} /> |                 <Message {...passwordChangedMessages.skipThisStep} /> | ||||||
|             </a> |             </a> | ||||||
|         ) |         ) | ||||||
|     }; |     }; | ||||||
|  | 
 | ||||||
|  |     componentsMap.Links.contextTypes = { | ||||||
|  |         reject: PropTypes.func.isRequired | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return componentsMap; | ||||||
| } | } | ||||||
| @@ -7,22 +7,16 @@ import buttons from 'components/ui/buttons.scss'; | |||||||
| import icons from 'components/ui/icons.scss'; | import icons from 'components/ui/icons.scss'; | ||||||
| import { PanelBodyHeader } from 'components/ui/Panel'; | import { PanelBodyHeader } from 'components/ui/Panel'; | ||||||
| 
 | 
 | ||||||
| import BaseAuthBody from './BaseAuthBody'; | import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||||
| import styles from './permissions.scss'; | import styles from './permissions.scss'; | ||||||
| import messages from './Permissions.messages'; | import messages from './Permissions.messages'; | ||||||
| 
 | 
 | ||||||
| class Body extends BaseAuthBody { | class Body extends BaseAuthBody { | ||||||
|     static propTypes = { |     static displayName = 'PermissionsBody'; | ||||||
|         ...BaseAuthBody.propTypes, |  | ||||||
|         auth: PropTypes.shape({ |  | ||||||
|             error: PropTypes.string, |  | ||||||
|             scopes: PropTypes.array.isRequired |  | ||||||
|         }) |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     render() { |     render() { | ||||||
|         const {user} = this.props; |         const {user} = this.context; | ||||||
|         const scopes = this.props.auth.scopes; |         const scopes = this.context.auth.scopes; | ||||||
| 
 | 
 | ||||||
|         return ( |         return ( | ||||||
|             <div> |             <div> | ||||||
| @@ -61,7 +55,7 @@ class Body extends BaseAuthBody { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default function Permissions() { | export default function Permissions() { | ||||||
|     return { |     const componentsMap = { | ||||||
|         Title: () => ( // TODO: separate component for PageTitle |         Title: () => ( // TODO: separate component for PageTitle | ||||||
|             <Message {...messages.permissionsTitle}> |             <Message {...messages.permissionsTitle}> | ||||||
|                 {(msg) => <span>{msg}<Helmet title={msg} /></span>} |                 {(msg) => <span>{msg}<Helmet title={msg} /></span>} | ||||||
| @@ -73,14 +67,20 @@ export default function Permissions() { | |||||||
|                 <Message {...messages.approve} /> |                 <Message {...messages.approve} /> | ||||||
|             </button> |             </button> | ||||||
|         ), |         ), | ||||||
|         Links: (props) => ( |         Links: (props, context) => ( | ||||||
|             <a href="#" onClick={(event) => { |             <a href="#" onClick={(event) => { | ||||||
|                 event.preventDefault(); |                 event.preventDefault(); | ||||||
| 
 | 
 | ||||||
|                 props.reject(); |                 context.reject(); | ||||||
|             }}> |             }}> | ||||||
|                 <Message {...messages.decline} /> |                 <Message {...messages.decline} /> | ||||||
|             </a> |             </a> | ||||||
|         ) |         ) | ||||||
|     }; |     }; | ||||||
|  | 
 | ||||||
|  |     componentsMap.Links.contextTypes = { | ||||||
|  |         reject: PropTypes.func.isRequired | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     return componentsMap; | ||||||
| } | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| import React, { PropTypes } from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| import { FormattedMessage as Message } from 'react-intl'; | import { FormattedMessage as Message } from 'react-intl'; | ||||||
| import Helmet from 'react-helmet'; | import Helmet from 'react-helmet'; | ||||||
| @@ -6,27 +6,14 @@ import Helmet from 'react-helmet'; | |||||||
| import buttons from 'components/ui/buttons.scss'; | import buttons from 'components/ui/buttons.scss'; | ||||||
| import { Input, Checkbox } from 'components/ui/Form'; | import { Input, Checkbox } from 'components/ui/Form'; | ||||||
| 
 | 
 | ||||||
| import BaseAuthBody from './BaseAuthBody'; | import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||||
|  | import activationMessages from 'components/auth/activation/Activation.messages'; | ||||||
| import messages from './Register.messages'; | import messages from './Register.messages'; | ||||||
| import activationMessages from './Activation.messages'; |  | ||||||
| 
 | 
 | ||||||
| // TODO: password and username can be validate for length and sameness | // TODO: password and username can be validate for length and sameness | ||||||
| 
 | 
 | ||||||
| class Body extends BaseAuthBody { | class Body extends BaseAuthBody { | ||||||
|     static propTypes = { |     static displayName = 'RegisterBody'; | ||||||
|         ...BaseAuthBody.propTypes, |  | ||||||
|         register: PropTypes.func.isRequired, |  | ||||||
|         auth: PropTypes.shape({ |  | ||||||
|             error: PropTypes.string, |  | ||||||
|             register: PropTypes.shape({ |  | ||||||
|                 email: PropTypes.string, |  | ||||||
|                 username: PropTypes.stirng, |  | ||||||
|                 password: PropTypes.stirng, |  | ||||||
|                 rePassword: PropTypes.stirng, |  | ||||||
|                 rulesAgreement: PropTypes.boolean |  | ||||||
|             }) |  | ||||||
|         }) |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     render() { |     render() { | ||||||
|         return ( |         return ( | ||||||
| @@ -38,6 +25,7 @@ class Body extends BaseAuthBody { | |||||||
|                     color="blue" |                     color="blue" | ||||||
|                     type="text" |                     type="text" | ||||||
|                     autoFocus |                     autoFocus | ||||||
|  |                     onFocus={this.fixAutoFocus} | ||||||
|                     required |                     required | ||||||
|                     placeholder={messages.yourNickname} |                     placeholder={messages.yourNickname} | ||||||
|                 /> |                 /> | ||||||
| @@ -14,7 +14,7 @@ export class Input extends Component { | |||||||
|             id: PropTypes.string |             id: PropTypes.string | ||||||
|         }), |         }), | ||||||
|         icon: PropTypes.string, |         icon: PropTypes.string, | ||||||
|         color: PropTypes.oneOf(['green', 'blue', 'red']) |         color: PropTypes.oneOf(['green', 'blue', 'red', 'lightViolet', 'darkBlue']) | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     static contextTypes = { |     static contextTypes = { | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/index.js
									
									
									
									
									
								
							| @@ -22,19 +22,6 @@ import routesFactory from 'routes'; | |||||||
|  |  | ||||||
| import 'index.scss'; | import 'index.scss'; | ||||||
|  |  | ||||||
| // TODO: временная мера против Intl, который беспощадно спамит консоль |  | ||||||
| if (process.env.NODE_ENV !== 'production') { |  | ||||||
|     const originalConsoleError = console.error; |  | ||||||
|     if (console.error === originalConsoleError) { |  | ||||||
|         console.error = (...args) => { |  | ||||||
|             if (args[0].indexOf('[React Intl] Missing message:') === 0) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|             originalConsoleError.call(console, ...args); |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const reducer = combineReducers({ | const reducer = combineReducers({ | ||||||
|     ...reducers, |     ...reducers, | ||||||
|     routing: routeReducer |     routing: routeReducer | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react'; | |||||||
|  |  | ||||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||||
|  |  | ||||||
| import AppInfo from 'components/auth/AppInfo'; | import AppInfo from 'components/auth/appInfo/AppInfo'; | ||||||
| import PanelTransition from 'components/auth/PanelTransition'; | import PanelTransition from 'components/auth/PanelTransition'; | ||||||
|  |  | ||||||
| import Finish from 'components/auth/Finish'; | import Finish from 'components/auth/Finish'; | ||||||
|   | |||||||
| @@ -2,17 +2,9 @@ import React, { Component } from 'react'; | |||||||
|  |  | ||||||
| import { connect } from 'react-redux'; | import { connect } from 'react-redux'; | ||||||
|  |  | ||||||
| import authFlow from 'services/authFlow'; |  | ||||||
|  |  | ||||||
| class IndexPage extends Component { | class IndexPage extends Component { | ||||||
|     displayName = 'IndexPage'; |     displayName = 'IndexPage'; | ||||||
|  |  | ||||||
|     componentWillMount() { |  | ||||||
|         if (this.props.user.isGuest) { |  | ||||||
|             authFlow.login(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     render() { |     render() { | ||||||
|         const {user, children} = this.props; |         const {user, children} = this.props; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,14 +8,14 @@ import AuthPage from 'pages/auth/AuthPage'; | |||||||
| import { authenticate } from 'components/user/actions'; | import { authenticate } from 'components/user/actions'; | ||||||
|  |  | ||||||
| import OAuthInit from 'components/auth/OAuthInit'; | import OAuthInit from 'components/auth/OAuthInit'; | ||||||
| import Register from 'components/auth/Register'; | import Register from 'components/auth/register/Register'; | ||||||
| import Login from 'components/auth/Login'; | import Login from 'components/auth/login/Login'; | ||||||
| import Permissions from 'components/auth/Permissions'; | import Permissions from 'components/auth/permissions/Permissions'; | ||||||
| import Activation from 'components/auth/Activation'; | import Activation from 'components/auth/activation/Activation'; | ||||||
| import Password from 'components/auth/Password'; | import Password from 'components/auth/password/Password'; | ||||||
| import Logout from 'components/auth/Logout'; | import Logout from 'components/auth/Logout'; | ||||||
| import PasswordChange from 'components/auth/PasswordChange'; | import PasswordChange from 'components/auth/passwordChange/PasswordChange'; | ||||||
| import ForgotPassword from 'components/auth/ForgotPassword'; | import ForgotPassword from 'components/auth/forgotPassword/ForgotPassword'; | ||||||
| import Finish from 'components/auth/Finish'; | import Finish from 'components/auth/Finish'; | ||||||
|  |  | ||||||
| import authFlow from 'services/authFlow'; | import authFlow from 'services/authFlow'; | ||||||
| @@ -35,7 +35,7 @@ export default function routesFactory(store) { | |||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <Route path="/" component={RootPage}> |         <Route path="/" component={RootPage}> | ||||||
|             <IndexRoute component={IndexPage} /> |             <IndexRoute component={IndexPage} {...onEnter} /> | ||||||
|  |  | ||||||
|             <Route path="oauth" component={OAuthInit} {...onEnter} /> |             <Route path="oauth" component={OAuthInit} {...onEnter} /> | ||||||
|             <Route path="logout" component={Logout} {...onEnter} /> |             <Route path="logout" component={Logout} {...onEnter} /> | ||||||
|   | |||||||
| @@ -23,7 +23,6 @@ export default class AuthFlow { | |||||||
|             const {routing} = this.getState(); |             const {routing} = this.getState(); | ||||||
|  |  | ||||||
|             if (routing.location.pathname !== route) { |             if (routing.location.pathname !== route) { | ||||||
|                 this.ignoreRequest = true; // TODO: remove me |  | ||||||
|                 if (this.replace) { |                 if (this.replace) { | ||||||
|                     this.replace(route); |                     this.replace(route); | ||||||
|                 } |                 } | ||||||
| @@ -62,10 +61,10 @@ export default class AuthFlow { | |||||||
|             throw new Error('State is required'); |             throw new Error('State is required'); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (this.state instanceof state.constructor) { |         // if (this.state instanceof state.constructor) { | ||||||
|             // already in this state |         //     // already in this state | ||||||
|             return; |         //     return; | ||||||
|         } |         // } | ||||||
|  |  | ||||||
|         this.state && this.state.leave(this); |         this.state && this.state.leave(this); | ||||||
|         this.state = state; |         this.state = state; | ||||||
| @@ -74,10 +73,6 @@ export default class AuthFlow { | |||||||
|  |  | ||||||
|     handleRequest(path, replace) { |     handleRequest(path, replace) { | ||||||
|         this.replace = replace; |         this.replace = replace; | ||||||
|         if (this.ignoreRequest) { |  | ||||||
|             this.ignoreRequest = false; |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         switch (path) { |         switch (path) { | ||||||
|             case '/oauth': |             case '/oauth': | ||||||
| @@ -92,6 +87,7 @@ export default class AuthFlow { | |||||||
|                 this.setState(new ForgotPasswordState()); |                 this.setState(new ForgotPasswordState()); | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|  |             case '/': | ||||||
|             case '/login': |             case '/login': | ||||||
|             case '/password': |             case '/password': | ||||||
|             case '/activation': |             case '/activation': | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user