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", | ||||
|     "intl-format-cache": "^2.0.4", | ||||
|     "intl-messageformat": "^1.1.0", | ||||
|     "react": "^0.14.0", | ||||
|     "react-dom": "^0.14.3", | ||||
|     "react": "^15.0.0-rc.1", | ||||
|     "react-dom": "^15.0.0-rc.1", | ||||
|     "react-height": "^2.0.3", | ||||
|     "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-redux": "^4.0.0", | ||||
|     "react-router": "^2.0.0", | ||||
|   | ||||
| @@ -3,30 +3,33 @@ | ||||
|  */ | ||||
| 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 { | ||||
|     static propTypes = { | ||||
|     static contextTypes = { | ||||
|         clearErrors: PropTypes.func.isRequired, | ||||
|         resolve: PropTypes.func.isRequired, | ||||
|         reject: PropTypes.func.isRequired, | ||||
|         auth: PropTypes.shape({ | ||||
|             error: PropTypes.string | ||||
|         }) | ||||
|             error: PropTypes.string, | ||||
|             scopes: PropTypes.array | ||||
|         }), | ||||
|         user: userShape | ||||
|     }; | ||||
|  | ||||
|     renderErrors() { | ||||
|         return this.props.auth.error | ||||
|             ? <AuthError error={this.props.auth.error} onClose={this.onClearErrors} /> | ||||
|         return this.context.auth.error | ||||
|             ? <AuthError error={this.context.auth.error} onClose={this.onClearErrors} /> | ||||
|             : '' | ||||
|             ; | ||||
|     } | ||||
|  | ||||
|     onFormSubmit() { | ||||
|         this.props.resolve(this.serialize()); | ||||
|         this.context.resolve(this.serialize()); | ||||
|     } | ||||
|  | ||||
|     onClearErrors = this.props.clearErrors; | ||||
|     onClearErrors = this.context.clearErrors; | ||||
|  | ||||
|     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() { | ||||
|         return Object.keys(this.form).reduce((acc, key) => { | ||||
|             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 icons from 'components/ui/icons.scss'; | ||||
| import authFlow from 'services/authFlow'; | ||||
| import { userShape } from 'components/user/User'; | ||||
|  | ||||
| import * as actions from './actions'; | ||||
|  | ||||
| @@ -21,6 +22,7 @@ class PanelTransition extends Component { | ||||
|     static displayName = 'PanelTransition'; | ||||
|  | ||||
|     static propTypes = { | ||||
|         // context props | ||||
|         auth: PropTypes.shape({ | ||||
|             error: PropTypes.string, | ||||
|             login: PropTypes.shape({ | ||||
| @@ -28,8 +30,13 @@ class PanelTransition extends Component { | ||||
|                 password: PropTypes.string | ||||
|             }) | ||||
|         }).isRequired, | ||||
|         user: userShape.isRequired, | ||||
|         setError: 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, | ||||
|         Title: PropTypes.element.isRequired, | ||||
|         Body: PropTypes.element.isRequired, | ||||
| @@ -37,6 +44,30 @@ class PanelTransition extends Component { | ||||
|         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 = { | ||||
|         height: {}, | ||||
|         contextHeight: 0 | ||||
| @@ -91,7 +122,7 @@ class PanelTransition extends Component { | ||||
|  | ||||
|                     const contentHeight = { | ||||
|                         overflow: 'hidden', | ||||
|                         height: forceHeight ? common.switchContextHeightSpring : 'auto' | ||||
|                         height: forceHeight ? common.style.switchContextHeightSpring : 'auto' | ||||
|                     }; | ||||
|  | ||||
|                     const bodyHeight = { | ||||
| @@ -141,6 +172,7 @@ class PanelTransition extends Component { | ||||
|  | ||||
|     /** | ||||
|      * @param  {Object} config | ||||
|      * @param  {string} config.key | ||||
|      * @param  {Object} [options] | ||||
|      * @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}> | ||||
|                 {hasBackButton ? backButton : null} | ||||
|                 <div style={scrollStyle}> | ||||
|                     {React.cloneElement(Title, this.props)} | ||||
|                     {Title} | ||||
|                 </div> | ||||
|             </div> | ||||
|         ); | ||||
| @@ -263,7 +295,6 @@ class PanelTransition extends Component { | ||||
|         return ( | ||||
|             <ReactHeight key={`body${key}`} style={style} onHeightReady={this.onUpdateHeight}> | ||||
|                 {React.cloneElement(Body, { | ||||
|                     ...this.props, | ||||
|                     ref: (body) => { | ||||
|                         this.body = body; | ||||
|                     } | ||||
| @@ -279,7 +310,7 @@ class PanelTransition extends Component { | ||||
|  | ||||
|         return ( | ||||
|             <div key={`footer${key}`} style={style}> | ||||
|                 {React.cloneElement(Footer, this.props)} | ||||
|                 {Footer} | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
| @@ -291,15 +322,15 @@ class PanelTransition extends Component { | ||||
|  | ||||
|         return ( | ||||
|             <div key={`links${key}`} style={style}> | ||||
|                 {React.cloneElement(Links, this.props)} | ||||
|                 {Links} | ||||
|             </div> | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param  {string} key | ||||
|      * @param  {Object} props | ||||
|      * @param  {number} props.opacitySpring | ||||
|      * @param  {Object} style | ||||
|      * @param  {number} style.opacitySpring | ||||
|      * | ||||
|      * @return {Object} | ||||
|      */ | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import React, { PropTypes } from 'react'; | ||||
| import React from 'react'; | ||||
| 
 | ||||
| import { FormattedMessage as Message } from 'react-intl'; | ||||
| import Helmet from 'react-helmet'; | ||||
| @@ -6,20 +6,12 @@ import Helmet from 'react-helmet'; | ||||
| import buttons from 'components/ui/buttons.scss'; | ||||
| import { Input } from 'components/ui/Form'; | ||||
| 
 | ||||
| import BaseAuthBody from './BaseAuthBody'; | ||||
| import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||
| import styles from './activation.scss'; | ||||
| import messages from './Activation.messages'; | ||||
| 
 | ||||
| class Body extends BaseAuthBody { | ||||
|     static propTypes = { | ||||
|         ...BaseAuthBody.propTypes, | ||||
|         auth: PropTypes.shape({ | ||||
|             error: PropTypes.string, | ||||
|             login: PropTypes.shape({ | ||||
|                 login: PropTypes.stirng | ||||
|             }) | ||||
|         }) | ||||
|     }; | ||||
|     static displayName = 'ActivationBody'; | ||||
| 
 | ||||
|     render() { | ||||
|         return ( | ||||
| @@ -31,7 +23,7 @@ class Body extends BaseAuthBody { | ||||
| 
 | ||||
|                     <div className={styles.descriptionText}> | ||||
|                         <Message {...messages.activationMailWasSent} values={{ | ||||
|                             email: (<b>{this.props.user.email}</b>) | ||||
|                             email: (<b>{this.context.user.email}</b>) | ||||
|                         }} /> | ||||
|                     </div> | ||||
|                 </div> | ||||
| @@ -40,6 +32,7 @@ class Body extends BaseAuthBody { | ||||
|                         color="blue" | ||||
|                         className={styles.activationCodeInput} | ||||
|                         autoFocus | ||||
|                         onFocus={this.fixAutoFocus} | ||||
|                         required | ||||
|                         placeholder={messages.enterTheCode} | ||||
|                     /> | ||||
| @@ -11,8 +11,8 @@ export default class AppInfo extends Component { | ||||
|     static displayName = 'AppInfo'; | ||||
| 
 | ||||
|     static propTypes = { | ||||
|         name: PropTypes.string.isRequired, | ||||
|         description: PropTypes.string.isRequired, | ||||
|         name: PropTypes.string, | ||||
|         description: PropTypes.string, | ||||
|         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 Helmet from 'react-helmet'; | ||||
| @@ -6,22 +6,13 @@ import Helmet from 'react-helmet'; | ||||
| import buttons from 'components/ui/buttons.scss'; | ||||
| import { Input } from 'components/ui/Form'; | ||||
| 
 | ||||
| import BaseAuthBody from './BaseAuthBody'; | ||||
| import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||
| import messages from './ForgotPassword.messages'; | ||||
| 
 | ||||
| import styles from './forgotPassword.scss'; | ||||
| 
 | ||||
| class Body extends BaseAuthBody { | ||||
|     static propTypes = { | ||||
|         ...BaseAuthBody.propTypes, | ||||
|         //login: PropTypes.func.isRequired, | ||||
|         auth: PropTypes.shape({ | ||||
|             error: PropTypes.string, | ||||
|             login: PropTypes.shape({ | ||||
|                 email: PropTypes.stirng | ||||
|             }) | ||||
|         }) | ||||
|     }; | ||||
|     static displayName = 'ForgotPasswordBody'; | ||||
| 
 | ||||
|     // Если юзер вводил своё мыло во время попытки авторизации, то почему бы его сюда автоматически не подставить? | ||||
|     render() { | ||||
| @@ -37,6 +28,7 @@ class Body extends BaseAuthBody { | ||||
|                     icon="envelope" | ||||
|                     color="lightViolet" | ||||
|                     autoFocus | ||||
|                     onFocus={this.fixAutoFocus} | ||||
|                     required | ||||
|                     placeholder={messages.accountEmail} | ||||
|                 /> | ||||
| @@ -49,7 +41,6 @@ class Body extends BaseAuthBody { | ||||
| 
 | ||||
|     onFormSubmit() { | ||||
|         // 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 Helmet from 'react-helmet'; | ||||
| @@ -7,20 +7,12 @@ import { Link } from 'react-router'; | ||||
| import buttons from 'components/ui/buttons.scss'; | ||||
| 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 passwordMessages from './Password.messages'; | ||||
| 
 | ||||
| class Body extends BaseAuthBody { | ||||
|     static propTypes = { | ||||
|         ...BaseAuthBody.propTypes, | ||||
|         auth: PropTypes.shape({ | ||||
|             error: PropTypes.string, | ||||
|             login: PropTypes.shape({ | ||||
|                 login: PropTypes.stirng | ||||
|             }) | ||||
|         }) | ||||
|     }; | ||||
|     static displayName = 'LoginBody'; | ||||
| 
 | ||||
|     render() { | ||||
|         return ( | ||||
| @@ -30,6 +22,7 @@ class Body extends BaseAuthBody { | ||||
|                 <Input {...this.bindField('login')} | ||||
|                     icon="envelope" | ||||
|                     autoFocus | ||||
|                     onFocus={this.fixAutoFocus} | ||||
|                     required | ||||
|                     placeholder={messages.emailOrUsername} | ||||
|                 /> | ||||
| @@ -1,4 +1,4 @@ | ||||
| import React, { PropTypes } from 'react'; | ||||
| import React from 'react'; | ||||
| 
 | ||||
| import { FormattedMessage as Message } from 'react-intl'; | ||||
| import Helmet from 'react-helmet'; | ||||
| @@ -8,24 +8,15 @@ import buttons from 'components/ui/buttons.scss'; | ||||
| import icons from 'components/ui/icons.scss'; | ||||
| import { Input, Checkbox } from 'components/ui/Form'; | ||||
| 
 | ||||
| import BaseAuthBody from './BaseAuthBody'; | ||||
| import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||
| import styles from './password.scss'; | ||||
| import messages from './Password.messages'; | ||||
| 
 | ||||
| class Body extends BaseAuthBody { | ||||
|     static propTypes = { | ||||
|         ...BaseAuthBody.propTypes, | ||||
|         auth: PropTypes.shape({ | ||||
|             error: PropTypes.string, | ||||
|             login: PropTypes.shape({ | ||||
|                 login: PropTypes.stirng, | ||||
|                 password: PropTypes.stirng | ||||
|             }) | ||||
|         }) | ||||
|     }; | ||||
|     static displayName = 'PasswordBody'; | ||||
| 
 | ||||
|     render() { | ||||
|         const {user} = this.props; | ||||
|         const {user} = this.context; | ||||
| 
 | ||||
|         return ( | ||||
|             <div> | ||||
| @@ -46,6 +37,7 @@ class Body extends BaseAuthBody { | ||||
|                     icon="key" | ||||
|                     type="password" | ||||
|                     autoFocus | ||||
|                     onFocus={this.fixAutoFocus} | ||||
|                     required | ||||
|                     placeholder={messages.accountPassword} | ||||
|                 /> | ||||
| @@ -2,21 +2,18 @@ import React, { PropTypes } from 'react'; | ||||
| 
 | ||||
| import { FormattedMessage as Message } from 'react-intl'; | ||||
| import Helmet from 'react-helmet'; | ||||
| import { Link } from 'react-router'; | ||||
| 
 | ||||
| import buttons from 'components/ui/buttons.scss'; | ||||
| import { Input } from 'components/ui/Form'; | ||||
| 
 | ||||
| import BaseAuthBody from './BaseAuthBody'; | ||||
| import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||
| import passwordChangedMessages from './PasswordChange.messages'; | ||||
| 
 | ||||
| import icons from 'components/ui/icons.scss'; | ||||
| import styles from './passwordChange.scss'; | ||||
| 
 | ||||
| class Body extends BaseAuthBody { | ||||
|     static propTypes = { | ||||
|         ...BaseAuthBody.propTypes | ||||
|     }; | ||||
|     static displayName = 'PasswordChangeBody'; | ||||
| 
 | ||||
|     render() { | ||||
|         return ( | ||||
| @@ -35,6 +32,7 @@ class Body extends BaseAuthBody { | ||||
|                     icon="key" | ||||
|                     color="darkBlue" | ||||
|                     autoFocus | ||||
|                     onFocus={this.fixAutoFocus} | ||||
|                     required | ||||
|                     placeholder={passwordChangedMessages.newPassword} | ||||
|                 /> | ||||
| @@ -51,7 +49,7 @@ class Body extends BaseAuthBody { | ||||
| } | ||||
| 
 | ||||
| export default function PasswordChange() { | ||||
|     return { | ||||
|     const componentsMap = { | ||||
|         Title: () => ( // TODO: separate component for PageTitle | ||||
|             <Message {...passwordChangedMessages.changePasswordTitle}> | ||||
|                 {(msg) => <span>{msg}<Helmet title={msg} /></span>} | ||||
| @@ -63,14 +61,20 @@ export default function PasswordChange() { | ||||
|                 <Message {...passwordChangedMessages.change} /> | ||||
|             </button> | ||||
|         ), | ||||
|         Links: (props) => ( | ||||
|         Links: (props, context) => ( | ||||
|             <a href="#" onClick={(event) => { | ||||
|                 event.preventDefault(); | ||||
| 
 | ||||
|                 props.reject(); | ||||
|                 context.reject(); | ||||
|             }}> | ||||
|                 <Message {...passwordChangedMessages.skipThisStep} /> | ||||
|             </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 { PanelBodyHeader } from 'components/ui/Panel'; | ||||
| 
 | ||||
| import BaseAuthBody from './BaseAuthBody'; | ||||
| import BaseAuthBody from 'components/auth/BaseAuthBody'; | ||||
| import styles from './permissions.scss'; | ||||
| import messages from './Permissions.messages'; | ||||
| 
 | ||||
| class Body extends BaseAuthBody { | ||||
|     static propTypes = { | ||||
|         ...BaseAuthBody.propTypes, | ||||
|         auth: PropTypes.shape({ | ||||
|             error: PropTypes.string, | ||||
|             scopes: PropTypes.array.isRequired | ||||
|         }) | ||||
|     }; | ||||
|     static displayName = 'PermissionsBody'; | ||||
| 
 | ||||
|     render() { | ||||
|         const {user} = this.props; | ||||
|         const scopes = this.props.auth.scopes; | ||||
|         const {user} = this.context; | ||||
|         const scopes = this.context.auth.scopes; | ||||
| 
 | ||||
|         return ( | ||||
|             <div> | ||||
| @@ -61,7 +55,7 @@ class Body extends BaseAuthBody { | ||||
| } | ||||
| 
 | ||||
| export default function Permissions() { | ||||
|     return { | ||||
|     const componentsMap = { | ||||
|         Title: () => ( // TODO: separate component for PageTitle | ||||
|             <Message {...messages.permissionsTitle}> | ||||
|                 {(msg) => <span>{msg}<Helmet title={msg} /></span>} | ||||
| @@ -73,14 +67,20 @@ export default function Permissions() { | ||||
|                 <Message {...messages.approve} /> | ||||
|             </button> | ||||
|         ), | ||||
|         Links: (props) => ( | ||||
|         Links: (props, context) => ( | ||||
|             <a href="#" onClick={(event) => { | ||||
|                 event.preventDefault(); | ||||
| 
 | ||||
|                 props.reject(); | ||||
|                 context.reject(); | ||||
|             }}> | ||||
|                 <Message {...messages.decline} /> | ||||
|             </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 Helmet from 'react-helmet'; | ||||
| @@ -6,27 +6,14 @@ import Helmet from 'react-helmet'; | ||||
| import buttons from 'components/ui/buttons.scss'; | ||||
| 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 activationMessages from './Activation.messages'; | ||||
| 
 | ||||
| // TODO: password and username can be validate for length and sameness | ||||
| 
 | ||||
| class Body extends BaseAuthBody { | ||||
|     static propTypes = { | ||||
|         ...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 | ||||
|             }) | ||||
|         }) | ||||
|     }; | ||||
|     static displayName = 'RegisterBody'; | ||||
| 
 | ||||
|     render() { | ||||
|         return ( | ||||
| @@ -38,6 +25,7 @@ class Body extends BaseAuthBody { | ||||
|                     color="blue" | ||||
|                     type="text" | ||||
|                     autoFocus | ||||
|                     onFocus={this.fixAutoFocus} | ||||
|                     required | ||||
|                     placeholder={messages.yourNickname} | ||||
|                 /> | ||||
| @@ -14,7 +14,7 @@ export class Input extends Component { | ||||
|             id: PropTypes.string | ||||
|         }), | ||||
|         icon: PropTypes.string, | ||||
|         color: PropTypes.oneOf(['green', 'blue', 'red']) | ||||
|         color: PropTypes.oneOf(['green', 'blue', 'red', 'lightViolet', 'darkBlue']) | ||||
|     }; | ||||
|  | ||||
|     static contextTypes = { | ||||
|   | ||||
							
								
								
									
										13
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/index.js
									
									
									
									
									
								
							| @@ -22,19 +22,6 @@ import routesFactory from 'routes'; | ||||
|  | ||||
| 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({ | ||||
|     ...reducers, | ||||
|     routing: routeReducer | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react'; | ||||
|  | ||||
| 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 Finish from 'components/auth/Finish'; | ||||
|   | ||||
| @@ -2,17 +2,9 @@ import React, { Component } from 'react'; | ||||
|  | ||||
| import { connect } from 'react-redux'; | ||||
|  | ||||
| import authFlow from 'services/authFlow'; | ||||
|  | ||||
| class IndexPage extends Component { | ||||
|     displayName = 'IndexPage'; | ||||
|  | ||||
|     componentWillMount() { | ||||
|         if (this.props.user.isGuest) { | ||||
|             authFlow.login(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     render() { | ||||
|         const {user, children} = this.props; | ||||
|  | ||||
|   | ||||
| @@ -8,14 +8,14 @@ import AuthPage from 'pages/auth/AuthPage'; | ||||
| import { authenticate } from 'components/user/actions'; | ||||
|  | ||||
| import OAuthInit from 'components/auth/OAuthInit'; | ||||
| import Register from 'components/auth/Register'; | ||||
| import Login from 'components/auth/Login'; | ||||
| import Permissions from 'components/auth/Permissions'; | ||||
| import Activation from 'components/auth/Activation'; | ||||
| import Password from 'components/auth/Password'; | ||||
| import Register from 'components/auth/register/Register'; | ||||
| import Login from 'components/auth/login/Login'; | ||||
| import Permissions from 'components/auth/permissions/Permissions'; | ||||
| import Activation from 'components/auth/activation/Activation'; | ||||
| import Password from 'components/auth/password/Password'; | ||||
| import Logout from 'components/auth/Logout'; | ||||
| import PasswordChange from 'components/auth/PasswordChange'; | ||||
| import ForgotPassword from 'components/auth/ForgotPassword'; | ||||
| import PasswordChange from 'components/auth/passwordChange/PasswordChange'; | ||||
| import ForgotPassword from 'components/auth/forgotPassword/ForgotPassword'; | ||||
| import Finish from 'components/auth/Finish'; | ||||
|  | ||||
| import authFlow from 'services/authFlow'; | ||||
| @@ -35,7 +35,7 @@ export default function routesFactory(store) { | ||||
|  | ||||
|     return ( | ||||
|         <Route path="/" component={RootPage}> | ||||
|             <IndexRoute component={IndexPage} /> | ||||
|             <IndexRoute component={IndexPage} {...onEnter} /> | ||||
|  | ||||
|             <Route path="oauth" component={OAuthInit} {...onEnter} /> | ||||
|             <Route path="logout" component={Logout} {...onEnter} /> | ||||
|   | ||||
| @@ -23,7 +23,6 @@ export default class AuthFlow { | ||||
|             const {routing} = this.getState(); | ||||
|  | ||||
|             if (routing.location.pathname !== route) { | ||||
|                 this.ignoreRequest = true; // TODO: remove me | ||||
|                 if (this.replace) { | ||||
|                     this.replace(route); | ||||
|                 } | ||||
| @@ -62,10 +61,10 @@ export default class AuthFlow { | ||||
|             throw new Error('State is required'); | ||||
|         } | ||||
|  | ||||
|         if (this.state instanceof state.constructor) { | ||||
|             // already in this state | ||||
|             return; | ||||
|         } | ||||
|         // if (this.state instanceof state.constructor) { | ||||
|         //     // already in this state | ||||
|         //     return; | ||||
|         // } | ||||
|  | ||||
|         this.state && this.state.leave(this); | ||||
|         this.state = state; | ||||
| @@ -74,10 +73,6 @@ export default class AuthFlow { | ||||
|  | ||||
|     handleRequest(path, replace) { | ||||
|         this.replace = replace; | ||||
|         if (this.ignoreRequest) { | ||||
|             this.ignoreRequest = false; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         switch (path) { | ||||
|             case '/oauth': | ||||
| @@ -92,6 +87,7 @@ export default class AuthFlow { | ||||
|                 this.setState(new ForgotPasswordState()); | ||||
|                 break; | ||||
|  | ||||
|             case '/': | ||||
|             case '/login': | ||||
|             case '/password': | ||||
|             case '/activation': | ||||
|   | ||||
		Reference in New Issue
	
	Block a user