diff --git a/.eslintrc.json b/.eslintrc.json
index f4c41fa..b6d1850 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -195,10 +195,10 @@
"react/jsx-indent-props": "warn",
"react/jsx-key": "warn",
"react/jsx-max-props-per-line": ["warn", {"maximum": 3}],
- "react/jsx-no-bind": "warn",
+ "react/jsx-no-bind": "off",
"react/jsx-no-duplicate-props": "warn",
"react/jsx-no-literals": "warn",
- "react/jsx-no-undef": "warn",
+ "react/jsx-no-undef": "error",
"react/jsx-pascal-case": "warn",
"react/jsx-uses-react": "warn",
"react/jsx-uses-vars": "warn",
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index a54682d..a5dc880 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -3789,9 +3789,9 @@
"dev": true
},
"history": {
- "version": "3.3.0",
- "from": "history@>=3.0.0 <4.0.0",
- "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz"
+ "version": "4.6.1",
+ "from": "history@>=4.5.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/history/-/history-4.6.1.tgz"
},
"hoek": {
"version": "2.16.3",
@@ -5991,7 +5991,8 @@
"query-string": {
"version": "4.3.4",
"from": "query-string@>=4.1.0 <5.0.0",
- "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz"
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+ "dev": true
},
"querystring": {
"version": "0.2.0",
@@ -6168,9 +6169,53 @@
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.4.tgz"
},
"react-router": {
- "version": "3.0.5",
- "from": "react-router@3.0.5",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-3.0.5.tgz"
+ "version": "4.1.1",
+ "from": "react-router@>=4.1.1 <5.0.0",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.1.1.tgz",
+ "dependencies": {
+ "invariant": {
+ "version": "2.2.2",
+ "from": "invariant@>=2.2.2 <3.0.0",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz"
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "from": "isarray@0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ },
+ "js-tokens": {
+ "version": "3.0.1",
+ "from": "js-tokens@^3.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz"
+ },
+ "loose-envify": {
+ "version": "1.3.1",
+ "from": "loose-envify@^1.3.1",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz"
+ },
+ "path-to-regexp": {
+ "version": "1.7.0",
+ "from": "path-to-regexp@>=1.5.3 <2.0.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz"
+ }
+ }
+ },
+ "react-router-dom": {
+ "version": "4.1.1",
+ "from": "react-router-dom@latest",
+ "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.1.1.tgz",
+ "dependencies": {
+ "js-tokens": {
+ "version": "3.0.1",
+ "from": "js-tokens@>=3.0.0 <4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz"
+ },
+ "loose-envify": {
+ "version": "1.3.1",
+ "from": "loose-envify@>=1.3.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz"
+ }
+ }
},
"react-side-effect": {
"version": "1.1.0",
@@ -6569,6 +6614,11 @@
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
"dev": true
},
+ "resolve-pathname": {
+ "version": "2.1.0",
+ "from": "resolve-pathname@>=2.0.0 <3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.1.0.tgz"
+ },
"restore-cursor": {
"version": "1.0.1",
"from": "restore-cursor@>=1.0.1 <2.0.0",
@@ -7052,7 +7102,8 @@
"strict-uri-encode": {
"version": "1.1.0",
"from": "strict-uri-encode@>=1.0.0 <2.0.0",
- "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz"
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "dev": true
},
"string_decoder": {
"version": "0.10.31",
@@ -7520,6 +7571,11 @@
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.7.tgz",
"dev": true
},
+ "url-search-params-polyfill": {
+ "version": "1.2.0",
+ "from": "url-search-params-polyfill@latest",
+ "resolved": "https://registry.npmjs.org/url-search-params-polyfill/-/url-search-params-polyfill-1.2.0.tgz"
+ },
"user-home": {
"version": "1.1.1",
"from": "user-home@>=1.1.1 <2.0.0",
@@ -7608,6 +7664,11 @@
"resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
"dev": true
},
+ "value-equal": {
+ "version": "0.2.1",
+ "from": "value-equal@>=0.2.0 <0.3.0",
+ "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.2.1.tgz"
+ },
"varstream": {
"version": "0.3.2",
"from": "varstream@>=0.3.2 <0.4.0",
diff --git a/package.json b/package.json
index e3cd40f..5840334 100644
--- a/package.json
+++ b/package.json
@@ -38,10 +38,11 @@
"react-intl": "^2.0.0",
"react-motion": "^0.4.0",
"react-redux": "^5.0.0",
- "react-router": "^3.0.0",
+ "react-router-dom": "^4.1.1",
"redux": "^3.0.4",
"redux-localstorage": "^0.4.1",
"redux-thunk": "^2.0.0",
+ "url-search-params-polyfill": "^1.2.0",
"webfontloader": "^1.6.26",
"whatwg-fetch": "^2.0.0"
},
diff --git a/src/components/accounts/AccountSwitcher.jsx b/src/components/accounts/AccountSwitcher.jsx
index 50cecea..3e4d018 100644
--- a/src/components/accounts/AccountSwitcher.jsx
+++ b/src/components/accounts/AccountSwitcher.jsx
@@ -1,7 +1,7 @@
import React, { Component, PropTypes } from 'react';
import classNames from 'classnames';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import { FormattedMessage as Message } from 'react-intl';
import loader from 'services/loader';
diff --git a/src/components/accounts/actions.js b/src/components/accounts/actions.js
index 54e76e7..5352c0d 100644
--- a/src/components/accounts/actions.js
+++ b/src/components/accounts/actions.js
@@ -1,4 +1,4 @@
-import { browserHistory } from 'react-router';
+import { browserHistory } from 'services/history';
import { sessionStorage } from 'services/localStorage';
import authentication from 'services/api/authentication';
diff --git a/src/components/auth/OAuthInit.jsx b/src/components/auth/OAuthInit.jsx
deleted file mode 100644
index c9ccd31..0000000
--- a/src/components/auth/OAuthInit.jsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import React, { Component } from 'react';
-
-export default class OAuthInit extends Component {
- static displayName = 'OAuthInit';
-
- render() {
- return ;
- }
-}
diff --git a/src/components/auth/acceptRules/AcceptRulesBody.jsx b/src/components/auth/acceptRules/AcceptRulesBody.jsx
index bb0c3bb..f72b88c 100644
--- a/src/components/auth/acceptRules/AcceptRulesBody.jsx
+++ b/src/components/auth/acceptRules/AcceptRulesBody.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { FormattedMessage as Message } from 'react-intl';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import icons from 'components/ui/icons.scss';
import BaseAuthBody from 'components/auth/BaseAuthBody';
diff --git a/src/components/auth/actions.js b/src/components/auth/actions.js
index 94ee292..52369a6 100644
--- a/src/components/auth/actions.js
+++ b/src/components/auth/actions.js
@@ -1,4 +1,4 @@
-import { browserHistory } from 'react-router';
+import { browserHistory } from 'services/history';
import logger from 'services/logger';
import localStorage from 'services/localStorage';
diff --git a/src/components/auth/activation/ActivationBody.jsx b/src/components/auth/activation/ActivationBody.jsx
index 2b257b7..c605695 100644
--- a/src/components/auth/activation/ActivationBody.jsx
+++ b/src/components/auth/activation/ActivationBody.jsx
@@ -13,15 +13,17 @@ export default class ActivationBody extends BaseAuthBody {
static panelId = 'activation';
static propTypes = {
- params: PropTypes.shape({
- key: PropTypes.string
+ match: PropTypes.shape({
+ params: PropTypes.shape({
+ key: PropTypes.string
+ })
})
};
- autoFocusField = this.props.params && this.props.params.key ? null : 'key';
+ autoFocusField = this.props.match.params && this.props.match.params.key ? null : 'key';
render() {
- const {key} = this.props.params;
+ const {key} = this.props.match.params;
const email = this.context.user.email;
return (
diff --git a/src/components/auth/recoverPassword/RecoverPasswordBody.jsx b/src/components/auth/recoverPassword/RecoverPasswordBody.jsx
index 1d35b38..29a4e3b 100644
--- a/src/components/auth/recoverPassword/RecoverPasswordBody.jsx
+++ b/src/components/auth/recoverPassword/RecoverPasswordBody.jsx
@@ -16,16 +16,18 @@ export default class RecoverPasswordBody extends BaseAuthBody {
static hasGoBack = true;
static propTypes = {
- params: PropTypes.shape({
- key: PropTypes.string
+ match: PropTypes.shape({
+ params: PropTypes.shape({
+ key: PropTypes.string
+ })
})
};
- autoFocusField = this.props.params && this.props.params.key ? 'newPassword' : 'key';
+ autoFocusField = this.props.match.params && this.props.match.params.key ? 'newPassword' : 'key';
render() {
const {user} = this.context;
- const {key} = this.props.params;
+ const {key} = this.props.match.params;
return (
diff --git a/src/components/auth/register/RegisterBody.jsx b/src/components/auth/register/RegisterBody.jsx
index 5338521..e2060de 100644
--- a/src/components/auth/register/RegisterBody.jsx
+++ b/src/components/auth/register/RegisterBody.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { FormattedMessage as Message } from 'react-intl';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import { Input, Checkbox, Captcha } from 'components/ui/form';
import BaseAuthBody from 'components/auth/BaseAuthBody';
diff --git a/src/components/footerMenu/FooterMenu.jsx b/src/components/footerMenu/FooterMenu.jsx
index dc46a5e..18eb43a 100644
--- a/src/components/footerMenu/FooterMenu.jsx
+++ b/src/components/footerMenu/FooterMenu.jsx
@@ -1,6 +1,6 @@
import React, { Component, PropTypes } from 'react';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import { FormattedMessage as Message } from 'react-intl';
import { LangMenu } from 'components/langMenu';
diff --git a/src/components/profile/Profile.jsx b/src/components/profile/Profile.jsx
index 9c93f30..ed27509 100644
--- a/src/components/profile/Profile.jsx
+++ b/src/components/profile/Profile.jsx
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { FormattedMessage as Message, FormattedRelative as Relative, FormattedHTMLMessage as HTMLMessage } from 'react-intl';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import Helmet from 'react-helmet';
import { userShape } from 'components/user/User';
@@ -15,7 +15,7 @@ import messages from './Profile.intl.json';
import RulesPage from 'pages/rules/RulesPage';
-export default class Profile extends Component {
+class Profile extends Component {
static displayName = 'Profile';
static propTypes = {
user: userShape
@@ -130,3 +130,9 @@ export default class Profile extends Component {
this.UUID = el;
}
}
+
+import { connect } from 'react-redux';
+
+export default connect((state) => ({
+ user: state.user
+}))(Profile);
diff --git a/src/components/profile/ProfileField.jsx b/src/components/profile/ProfileField.jsx
index bc40320..20a819d 100644
--- a/src/components/profile/ProfileField.jsx
+++ b/src/components/profile/ProfileField.jsx
@@ -1,6 +1,6 @@
import React, { Component, PropTypes } from 'react';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import styles from './profile.scss';
diff --git a/src/components/profile/ProfileForm.jsx b/src/components/profile/ProfileForm.jsx
index e39452d..ac6818d 100644
--- a/src/components/profile/ProfileForm.jsx
+++ b/src/components/profile/ProfileForm.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { FormattedMessage as Message } from 'react-intl';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import FormComponent from 'components/ui/form/FormComponent';
diff --git a/src/components/ui/popup/PopupStack.jsx b/src/components/ui/popup/PopupStack.jsx
index e319143..0292f00 100644
--- a/src/components/ui/popup/PopupStack.jsx
+++ b/src/components/ui/popup/PopupStack.jsx
@@ -1,7 +1,7 @@
import React, { Component, PropTypes } from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
-import { browserHistory } from 'react-router';
+import { browserHistory } from 'services/history';
import styles from './popup.scss';
@@ -18,7 +18,7 @@ export class PopupStack extends Component {
componentWillMount() {
document.addEventListener('keyup', this.onKeyPress);
- this.unlistenTransition = browserHistory.listenBefore(this.onRouteLeave);
+ this.unlistenTransition = browserHistory.listen(this.onRouteLeave);
}
componentWillUnmount() {
diff --git a/src/components/ui/scrollTo.js b/src/components/ui/scrollTo.js
deleted file mode 100644
index 1c3825e..0000000
--- a/src/components/ui/scrollTo.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Implements scroll to animation with momentum effect
- *
- * @see http://ariya.ofilabs.com/2013/11/javascript-kinetic-scrolling-part-2.html
- */
-
-import { rAF, getScrollTop } from 'functions';
-
-const TIME_CONSTANT = 100; // higher numbers - slower animation
-export function scrollTo(y) {
- const start = Date.now();
- let scrollWasTouched = false;
- rAF(() => { // wrap in rAF to optimize initial reading of scrollTop
- const contentHeight = document.documentElement.scrollHeight;
- const windowHeight = window.innerHeight;
- if (contentHeight < y + windowHeight) {
- y = contentHeight - windowHeight;
- }
-
- const amplitude = y - getScrollTop();
-
- (function animateScroll() {
- const elapsed = Date.now() - start;
-
- let delta = -amplitude * Math.exp(-elapsed / TIME_CONSTANT);
-
- if (Math.abs(delta) > 0.5 && !scrollWasTouched) {
- rAF(animateScroll);
- } else {
- delta = 0;
- document.removeEventListener('mousewheel', markScrollTouched);
- document.removeEventListener('touchstart', markScrollTouched);
- }
-
- if (scrollWasTouched) {
- return;
- }
-
- const newScrollTop = y + delta;
- window.scrollTo(0, newScrollTop);
- }());
- });
-
- document.addEventListener('mousewheel', markScrollTouched);
- document.addEventListener('touchstart', markScrollTouched);
- function markScrollTouched() {
- scrollWasTouched = true;
- }
-}
diff --git a/src/components/userbar/Userbar.jsx b/src/components/userbar/Userbar.jsx
index 60ebc90..d159231 100644
--- a/src/components/userbar/Userbar.jsx
+++ b/src/components/userbar/Userbar.jsx
@@ -1,6 +1,6 @@
import React, { Component, PropTypes } from 'react';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import { FormattedMessage as Message } from 'react-intl';
import buttons from 'components/ui/buttons.scss';
diff --git a/src/containers/AuthFlowRoute.jsx b/src/containers/AuthFlowRoute.jsx
new file mode 100644
index 0000000..332ce8d
--- /dev/null
+++ b/src/containers/AuthFlowRoute.jsx
@@ -0,0 +1,19 @@
+import { PropTypes } from 'react';
+import { Route } from 'react-router-dom';
+
+import AuthFlowRouteContents from './AuthFlowRouteContents';
+
+export default function AuthFlowRoute(props) {
+ const {component: Component, ...routeProps} = props;
+
+ return (
+
(
+
+ )}/>
+ );
+}
+
+AuthFlowRoute.propTypes = {
+ component: PropTypes.any,
+ routerProps: PropTypes.object
+};
diff --git a/src/containers/AuthFlowRouteContents.jsx b/src/containers/AuthFlowRouteContents.jsx
new file mode 100644
index 0000000..4d3f80d
--- /dev/null
+++ b/src/containers/AuthFlowRouteContents.jsx
@@ -0,0 +1,51 @@
+import { Component, PropTypes } from 'react';
+import { Redirect } from 'react-router-dom';
+
+import authFlow from 'services/authFlow';
+
+export default class AuthFlowRouteContents extends Component {
+ static propTypes = {
+ component: PropTypes.any,
+ routerProps: PropTypes.object
+ };
+
+ state = {
+ component: null
+ };
+
+ componentDidMount() {
+ this.handleProps(this.props);
+ }
+
+ componentWillReceiveProps(nextProps) {
+ this.handleProps(nextProps);
+ }
+
+ render() {
+ return this.state.component;
+ }
+
+ handleProps(props) {
+ const {routerProps} = props;
+
+ authFlow.handleRequest({
+ path: routerProps.location.pathname,
+ params: routerProps.match.params,
+ query: routerProps.location.query
+ }, this.onRedirect.bind(this), this.onRouteAllowed.bind(this, props));
+ }
+
+ onRedirect(path) {
+ this.setState({
+ component:
+ });
+ }
+
+ onRouteAllowed(props) {
+ const {component: Component} = props;
+
+ this.setState({
+ component:
+ });
+ }
+}
diff --git a/src/containers/PrivateRoute.jsx b/src/containers/PrivateRoute.jsx
new file mode 100644
index 0000000..d8bc315
--- /dev/null
+++ b/src/containers/PrivateRoute.jsx
@@ -0,0 +1,20 @@
+import authFlow from 'services/authFlow';
+import { Route, Redirect } from 'react-router-dom';
+import { connect } from 'react-redux';
+
+const PrivateRoute = ({user, component: Component, ...rest}) => (
+ (
+ user.isGuest ? (
+
+ ) : (
+
+ )
+ )}/>
+);
+
+export default connect((state) => ({
+ user: state.user
+}))(PrivateRoute);
diff --git a/src/functions.js b/src/functions.js
index 2759246..68a9595 100644
--- a/src/functions.js
+++ b/src/functions.js
@@ -92,3 +92,83 @@ export function getScrollTop() {
const doc = document.documentElement;
return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
}
+
+/**
+ * Implements scroll to animation with momentum effect
+ *
+ * @see http://ariya.ofilabs.com/2013/11/javascript-kinetic-scrolling-part-2.html
+ */
+
+const TIME_CONSTANT = 100; // higher numbers - slower animation
+export function scrollTo(y) {
+ const start = Date.now();
+ let scrollWasTouched = false;
+ rAF(() => { // wrap in rAF to optimize initial reading of scrollTop
+ const contentHeight = document.documentElement.scrollHeight;
+ const windowHeight = window.innerHeight;
+ if (contentHeight < y + windowHeight) {
+ y = contentHeight - windowHeight;
+ }
+
+ const amplitude = y - getScrollTop();
+
+ (function animateScroll() {
+ const elapsed = Date.now() - start;
+
+ let delta = -amplitude * Math.exp(-elapsed / TIME_CONSTANT);
+
+ if (Math.abs(delta) > 0.5 && !scrollWasTouched) {
+ rAF(animateScroll);
+ } else {
+ delta = 0;
+ document.removeEventListener('mousewheel', markScrollTouched);
+ document.removeEventListener('touchstart', markScrollTouched);
+ }
+
+ if (scrollWasTouched) {
+ return;
+ }
+
+ const newScrollTop = y + delta;
+ window.scrollTo(0, newScrollTop);
+ }());
+ });
+
+ document.addEventListener('mousewheel', markScrollTouched);
+ document.addEventListener('touchstart', markScrollTouched);
+ function markScrollTouched() {
+ scrollWasTouched = true;
+ }
+}
+
+const SCROLL_ANCHOR_OFFSET = 80; // 50 + 30 (header height + some spacing)
+// Первый скролл выполняется сразу после загрузки страницы, так что чтобы снизить
+// нагрузку на рендеринг мы откладываем первый скрол на 200ms
+let isFirstScroll = true;
+/**
+ * Scrolls to page's top or #anchor link, if any
+ */
+export function restoreScroll() {
+ const {hash} = location;
+
+ setTimeout(() => {
+ isFirstScroll = false;
+ const id = hash.replace('#', '');
+ const el = id ? document.getElementById(id) : null;
+ const viewPort = document.body;
+
+ if (!viewPort) {
+ console.log('Can not find viewPort element'); // eslint-disable-line
+ return;
+ }
+
+ let y = 0;
+ if (el) {
+ const {top} = el.getBoundingClientRect();
+
+ y = getScrollTop() + top - SCROLL_ANCHOR_OFFSET;
+ }
+
+ scrollTo(y, viewPort);
+ }, isFirstScroll ? 200 : 0);
+}
diff --git a/src/index.js b/src/index.js
index 14b7748..fd592c6 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,17 +4,19 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { Provider as ReduxProvider } from 'react-redux';
-import { Router, browserHistory } from 'react-router';
+import { Router, Route, Switch } from 'react-router-dom';
import { factory as userFactory } from 'components/user/factory';
import { IntlProvider } from 'components/i18n';
-import routesFactory from 'routes';
+import authFlow from 'services/authFlow';
import storeFactory from 'storeFactory';
import bsodFactory from 'components/ui/bsod/factory';
import loader from 'services/loader';
import logger from 'services/logger';
import font from 'services/font';
-import history from 'services/history';
+import history, { browserHistory } from 'services/history';
+import RootPage from 'pages/root/RootPage';
+import AuthFlowRoute from 'containers/AuthFlowRoute';
history.init();
@@ -24,7 +26,8 @@ logger.init({
const store = storeFactory();
-bsodFactory(store, stopLoading);
+bsodFactory(store, () => loader.hide());
+authFlow.setStore(store);
Promise.all([
userFactory(store),
@@ -34,11 +37,11 @@ Promise.all([
ReactDOM.render(
- {
- restoreScroll();
- stopLoading();
- }}>
- {routesFactory(store)}
+
+
+ null} />
+
+
,
@@ -48,45 +51,6 @@ Promise.all([
initAnalytics();
});
-
-function stopLoading() {
- loader.hide();
-}
-
-import { scrollTo } from 'components/ui/scrollTo';
-import { getScrollTop } from 'functions';
-const SCROLL_ANCHOR_OFFSET = 80; // 50 + 30 (header height + some spacing)
-// Первый скролл выполняется сразу после загрузки страницы, так что чтобы снизить
-// нагрузку на рендеринг мы откладываем первый скрол на 200ms
-let isFirstScroll = true;
-/**
- * Scrolls to page's top or #anchor link, if any
- */
-function restoreScroll() {
- const {hash} = location;
-
- setTimeout(() => {
- isFirstScroll = false;
- const id = hash.replace('#', '');
- const el = id ? document.getElementById(id) : null;
- const viewPort = document.body;
-
- if (!viewPort) {
- console.log('Can not find viewPort element'); // eslint-disable-line
- return;
- }
-
- let y = 0;
- if (el) {
- const {top} = el.getBoundingClientRect();
-
- y = getScrollTop() + top - SCROLL_ANCHOR_OFFSET;
- }
-
- scrollTo(y, viewPort);
- }, isFirstScroll ? 200 : 0);
-}
-
import { loadScript, debounce } from 'functions';
const trackPageView = debounce(_trackPageView);
function initAnalytics() {
diff --git a/src/pages/404/PageNotFound.jsx b/src/pages/404/PageNotFound.jsx
index 136d1fb..920be65 100644
--- a/src/pages/404/PageNotFound.jsx
+++ b/src/pages/404/PageNotFound.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import { FooterMenu } from 'components/footerMenu';
-import { Link } from 'react-router';
+import { Link } from 'react-router-dom';
import { FormattedMessage as Message } from 'react-intl';
import Helmet from 'react-helmet';
diff --git a/src/pages/auth/AuthPage.jsx b/src/pages/auth/AuthPage.jsx
index 4ee6fbd..08382aa 100644
--- a/src/pages/auth/AuthPage.jsx
+++ b/src/pages/auth/AuthPage.jsx
@@ -1,10 +1,22 @@
-import React, { Component, PropTypes } from 'react';
+import { Component, PropTypes } from 'react';
-import { connect } from 'react-redux';
+import { Route, Switch, Redirect } from 'react-router-dom';
import AppInfo from 'components/auth/appInfo/AppInfo';
import PanelTransition from 'components/auth/PanelTransition';
+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';
+import AcceptRules from 'components/auth/acceptRules/AcceptRules';
+import ForgotPassword from 'components/auth/forgotPassword/ForgotPassword';
+import RecoverPassword from 'components/auth/recoverPassword/RecoverPassword';
+import Finish from 'components/auth/finish/Finish';
+
import styles from './auth.scss';
class AuthPage extends Component {
@@ -31,7 +43,20 @@ class AuthPage extends Component {
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
@@ -44,7 +69,23 @@ class AuthPage extends Component {
};
}
+function renderPanelTransition(factory) {
+ const {Title, Body, Footer, Links} = factory();
+ return (props) => (
+ }
+ Body={