mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-12-02 11:41:04 +05:30
Очень грубо перенес текущие вьюхи на анимацию согласно прототипу
This commit is contained in:
parent
bea442c04b
commit
934afafce4
@ -20,6 +20,7 @@
|
|||||||
"intl-messageformat": "^1.1.0",
|
"intl-messageformat": "^1.1.0",
|
||||||
"react": "^0.14.0",
|
"react": "^0.14.0",
|
||||||
"react-dom": "^0.14.3",
|
"react-dom": "^0.14.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": "^2.0.0-beta-2",
|
||||||
"react-motion": "^0.3.1",
|
"react-motion": "^0.3.1",
|
||||||
|
@ -11,7 +11,51 @@ import styles from './activation.scss';
|
|||||||
import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
||||||
import messages from './Activation.messages';
|
import messages from './Activation.messages';
|
||||||
|
|
||||||
export default class Activation extends Component {
|
export default function Activation() {
|
||||||
|
var Title = () => ( // TODO: separate component for PageTitle
|
||||||
|
<Message {...messages.accountActivationTitle}>
|
||||||
|
{(msg) => <span>{msg}<Helmet title={msg} /></span>}
|
||||||
|
</Message>
|
||||||
|
);
|
||||||
|
Title.goBack = '/register';
|
||||||
|
|
||||||
|
return {
|
||||||
|
Title,
|
||||||
|
Body: () => (
|
||||||
|
<div>
|
||||||
|
<div className={styles.description}>
|
||||||
|
<div className={styles.descriptionImage} />
|
||||||
|
|
||||||
|
<div className={styles.descriptionText}>
|
||||||
|
<Message {...messages.activationMailWasSent} values={{
|
||||||
|
email: (<b>erickskrauch@yandex.ru</b>)
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={styles.formRow}>
|
||||||
|
<Input color="blue" className={styles.activationCodeInput} placeholder={messages.enterTheCode} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
Footer: (props) => (
|
||||||
|
<button className={buttons.blue} onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
props.history.push('/oauth/permissions');
|
||||||
|
}}>
|
||||||
|
<Message {...messages.confirmEmail} />
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
Links: () => (
|
||||||
|
<a href="#">
|
||||||
|
<Message {...messages.didNotReceivedEmail} />
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class _Activation extends Component {
|
||||||
displayName = 'Activation';
|
displayName = 'Activation';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -24,10 +24,5 @@ export default defineMessages({
|
|||||||
enterTheCode: {
|
enterTheCode: {
|
||||||
id: 'enterTheCode',
|
id: 'enterTheCode',
|
||||||
defaultMessage: 'Enter the code from E-mail here'
|
defaultMessage: 'Enter the code from E-mail here'
|
||||||
},
|
|
||||||
|
|
||||||
didNotReceivedEmail: {
|
|
||||||
id: 'didNotReceivedEmail',
|
|
||||||
defaultMessage: 'Did not received E-mail?'
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -13,7 +13,40 @@ import messages from './Login.messages';
|
|||||||
import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
||||||
import passwordMessages from './Password.messages';
|
import passwordMessages from './Password.messages';
|
||||||
|
|
||||||
class Login extends Component {
|
export default function Login() {
|
||||||
|
var context = {
|
||||||
|
onSubmit(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
this.props.push('/password');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
Title: () => ( // TODO: separate component for PageTitle
|
||||||
|
<Message {...messages.loginTitle}>
|
||||||
|
{(msg) => <span>{msg}<Helmet title={msg} /></span>}
|
||||||
|
</Message>
|
||||||
|
),
|
||||||
|
Body: () => <Input icon="envelope" type="email" placeholder={messages.emailOrUsername} />,
|
||||||
|
Footer: (props) => (
|
||||||
|
<button className={buttons.green} onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
props.history.push('/password');
|
||||||
|
}}>
|
||||||
|
<Message {...messages.next} />
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
Links: () => (
|
||||||
|
<a href="#">
|
||||||
|
<Message {...passwordMessages.forgotPassword} />
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class _Login extends Component {
|
||||||
displayName = 'Login';
|
displayName = 'Login';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -50,6 +83,6 @@ class Login extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default connect(null, {
|
// export connect(null, {
|
||||||
push: routeActions.push
|
// push: routeActions.push
|
||||||
})(Login);
|
// })(Login);
|
||||||
|
264
src/components/auth/PanelTransition.jsx
Normal file
264
src/components/auth/PanelTransition.jsx
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
|
||||||
|
import { TransitionMotion, spring } from 'react-motion';
|
||||||
|
import ReactHeight from 'react-height';
|
||||||
|
|
||||||
|
import { Panel, PanelBody, PanelFooter, PanelHeader } from 'components/ui/Panel';
|
||||||
|
import {helpLinks as helpLinksStyles} from 'components/auth/helpLinks.scss';
|
||||||
|
import panelStyles from 'components/ui/panel.scss';
|
||||||
|
import icons from 'components/ui/icons.scss';
|
||||||
|
|
||||||
|
|
||||||
|
const opacitySpringConfig = [200, 20];
|
||||||
|
const heightSpringConfig = [200, 18];
|
||||||
|
const transformSpringConfig = [500, 20];
|
||||||
|
|
||||||
|
// TODO: сделать более быстрый фейд на горизонтальном скролле
|
||||||
|
|
||||||
|
export default class PanelTransition extends Component {
|
||||||
|
state = {
|
||||||
|
height: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
componentWillReceiveProps() {
|
||||||
|
this.setState({
|
||||||
|
previousRoute: this.props.location
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
var {previousRoute, height} = this.state;
|
||||||
|
|
||||||
|
var {path, Title, Body, Footer, Links} = this.props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TransitionMotion
|
||||||
|
styles={{
|
||||||
|
[path]: {
|
||||||
|
Title,
|
||||||
|
Body,
|
||||||
|
Footer,
|
||||||
|
Links,
|
||||||
|
hasBackButton: previousRoute && previousRoute.pathname === Title.type.goBack,
|
||||||
|
transformSpring: spring(0),
|
||||||
|
opacitySpring: spring(1)
|
||||||
|
},
|
||||||
|
common: {
|
||||||
|
heightSpring: spring(height[path] || 0, heightSpringConfig)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
willEnter={this.willEnter}
|
||||||
|
willLeave={this.willLeave}
|
||||||
|
>
|
||||||
|
{(items) => {
|
||||||
|
var keys = Object.keys(items).filter((key) => key !== 'common');
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Panel>
|
||||||
|
<PanelHeader>
|
||||||
|
<div style={{
|
||||||
|
position: 'relative',
|
||||||
|
height: '59px',
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}>
|
||||||
|
{keys.map((key) => this.getHeader(key, items[key]))}
|
||||||
|
</div>
|
||||||
|
</PanelHeader>
|
||||||
|
<PanelBody style={{
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
position: 'relative',
|
||||||
|
height: previousRoute ? `${items.common.heightSpring}px` : `${height[path]}px`
|
||||||
|
}}>
|
||||||
|
{keys.map((key) => this.getBody(key, items[key]))}
|
||||||
|
</div>
|
||||||
|
</PanelBody>
|
||||||
|
<PanelFooter>
|
||||||
|
<div style={{
|
||||||
|
position: 'relative',
|
||||||
|
height: '50px',
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}>
|
||||||
|
{keys.map((key) => this.getFooter(key, items[key]))}
|
||||||
|
</div>
|
||||||
|
</PanelFooter>
|
||||||
|
</Panel>
|
||||||
|
<div className={helpLinksStyles} style={{position: 'relative', height: '20px'}}>
|
||||||
|
{keys.map((key) => this.getLinks(key, items[key]))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</TransitionMotion>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
willEnter = (key, styles) => {
|
||||||
|
var map = {
|
||||||
|
'/login': -1,
|
||||||
|
'/register': -1,
|
||||||
|
'/password': 1,
|
||||||
|
'/activation': 1,
|
||||||
|
'/oauth/permissions': 1
|
||||||
|
};
|
||||||
|
var sign = map[key];
|
||||||
|
|
||||||
|
return {
|
||||||
|
...styles,
|
||||||
|
transformSpring: spring(sign * 100, transformSpringConfig),
|
||||||
|
opacitySpring: spring(1, opacitySpringConfig)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
willLeave = (key, styles) => {
|
||||||
|
var map = {
|
||||||
|
'/login': -1,
|
||||||
|
'/register': -1,
|
||||||
|
'/password': 1,
|
||||||
|
'/activation': 1,
|
||||||
|
'/oauth/permissions': 1
|
||||||
|
};
|
||||||
|
var sign = map[key];
|
||||||
|
|
||||||
|
return {
|
||||||
|
...styles,
|
||||||
|
transformSpring: spring(sign * 100, transformSpringConfig),
|
||||||
|
opacitySpring: spring(0, opacitySpringConfig)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
updateHeight = (height) => {
|
||||||
|
this.setState({
|
||||||
|
height: {
|
||||||
|
...this.state.height,
|
||||||
|
[this.props.path]: height
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
onGoBack = (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
this.props.history.goBack();
|
||||||
|
};
|
||||||
|
|
||||||
|
getHeader(key, props) {
|
||||||
|
var {hasBackButton, transformSpring, Title} = props;
|
||||||
|
|
||||||
|
var style = {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: '100%'
|
||||||
|
};
|
||||||
|
|
||||||
|
var scrollStyle = {
|
||||||
|
WebkitTransform: `translateY(${transformSpring}%)`,
|
||||||
|
transform: `translateY(${transformSpring}%)`
|
||||||
|
};
|
||||||
|
|
||||||
|
var sideScrollStyle = {
|
||||||
|
position: 'relative',
|
||||||
|
zIndex: 2,
|
||||||
|
WebkitTransform: `translateX(${-Math.abs(transformSpring)}%)`,
|
||||||
|
transform: `translateX(${-Math.abs(transformSpring)}%)`
|
||||||
|
};
|
||||||
|
|
||||||
|
var backButton = (
|
||||||
|
<button style={sideScrollStyle} onClick={this.onGoBack} className={panelStyles.headerControl}>
|
||||||
|
<span className={icons.arrowLeft} />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={`header${key}`} style={style}>
|
||||||
|
{hasBackButton ? backButton : null}
|
||||||
|
<div style={scrollStyle}>
|
||||||
|
{Title}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getBody(key, props) {
|
||||||
|
var {transformSpring, opacitySpring, Body} = props;
|
||||||
|
|
||||||
|
var {previousRoute} = this.state;
|
||||||
|
|
||||||
|
var next = this.props.path;
|
||||||
|
var prev = previousRoute && previousRoute.pathname;
|
||||||
|
|
||||||
|
var not = (path) => prev !== path && next !== path;
|
||||||
|
|
||||||
|
var map = {
|
||||||
|
'/login': not('/password') ? 'Y' : 'X',
|
||||||
|
'/password': not('/login') ? 'Y' : 'X',
|
||||||
|
'/register': not('/activation') ? 'Y' : 'X',
|
||||||
|
'/activation': not('/register') ? 'Y' : 'X',
|
||||||
|
'/oauth/permissions': 'Y'
|
||||||
|
};
|
||||||
|
|
||||||
|
var direction = map[key];
|
||||||
|
|
||||||
|
if (direction === 'Y') {
|
||||||
|
transformSpring = Math.abs(transformSpring);
|
||||||
|
if (prev === key) {
|
||||||
|
transformSpring *= -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var style = {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: '100%',
|
||||||
|
WebkitTransform: `translate${direction}(${transformSpring}%)`,
|
||||||
|
transform: `translate${direction}(${transformSpring}%)`,
|
||||||
|
opacity: opacitySpring
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ReactHeight key={`body${key}`} style={style} onHeightReady={this.updateHeight}>
|
||||||
|
{Body}
|
||||||
|
</ReactHeight>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getFooter(key, props) {
|
||||||
|
var {opacitySpring, Footer} = props;
|
||||||
|
|
||||||
|
var style = {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: '100%',
|
||||||
|
opacity: opacitySpring
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={`footer${key}`} style={style}>
|
||||||
|
{Footer}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLinks(key, props) {
|
||||||
|
var {opacitySpring, Links} = props;
|
||||||
|
|
||||||
|
var style = {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: '100%',
|
||||||
|
opacity: opacitySpring
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={`links${key}`} style={style}>
|
||||||
|
{Links}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,62 @@ import styles from './password.scss';
|
|||||||
import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
||||||
import messages from './Password.messages';
|
import messages from './Password.messages';
|
||||||
|
|
||||||
export default class Password extends Component {
|
export default function Password() {
|
||||||
|
var Title = () => ( // TODO: separate component for PageTitle
|
||||||
|
<Message {...messages.passwordTitle}>
|
||||||
|
{(msg) => <span>{msg}<Helmet title={msg} /></span>}
|
||||||
|
</Message>
|
||||||
|
);
|
||||||
|
Title.goBack = '/login';
|
||||||
|
|
||||||
|
return {
|
||||||
|
Title,
|
||||||
|
Body: () => (
|
||||||
|
<div>
|
||||||
|
<PanelBodyHeader type="error">
|
||||||
|
<Message {...messages.invalidPassword} />
|
||||||
|
<br/>
|
||||||
|
<Message {...messages.suggestResetPassword} values={{
|
||||||
|
link: (
|
||||||
|
<a href="#">
|
||||||
|
<Message {...messages.forgotYourPassword} />
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
}} />
|
||||||
|
</PanelBodyHeader>
|
||||||
|
<div className={styles.miniProfile}>
|
||||||
|
<div className={styles.avatar}>
|
||||||
|
{/*<img src="//lorempixel.com/g/90/90" />*/}
|
||||||
|
<span className={icons.user} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.email}>
|
||||||
|
{/* На деле тут может быть и ник, в зависимости от того, что введут в 1 вьюху */}
|
||||||
|
erickskrauch@yandex.ru
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Input icon="key" type="password" placeholder={messages.accountPassword} />
|
||||||
|
|
||||||
|
<Checkbox label={<Message {...messages.rememberMe} />} />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
Footer: (props) => (
|
||||||
|
<button className={buttons.green} onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
props.history.push('/oauth/permissions');
|
||||||
|
}}>
|
||||||
|
<Message {...messages.signInButton} />
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
Links: () => (
|
||||||
|
<a href="#">
|
||||||
|
<Message {...messages.forgotPassword} />
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class _Password extends Component {
|
||||||
displayName = 'Password';
|
displayName = 'Password';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -11,7 +11,56 @@ import styles from './permissions.scss';
|
|||||||
import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
||||||
import messages from './Permissions.messages';
|
import messages from './Permissions.messages';
|
||||||
|
|
||||||
export default class Permissions extends Component {
|
export default function Permissions() {
|
||||||
|
return {
|
||||||
|
Title: () => ( // TODO: separate component for PageTitle
|
||||||
|
<Message {...messages.permissionsTitle}>
|
||||||
|
{(msg) => <span>{msg}<Helmet title={msg} /></span>}
|
||||||
|
</Message>
|
||||||
|
),
|
||||||
|
Body: () => (
|
||||||
|
<div>
|
||||||
|
<PanelBodyHeader>
|
||||||
|
<div className={styles.authInfo}>
|
||||||
|
<div className={styles.authInfoAvatar}>
|
||||||
|
{/*<img src="//lorempixel.com/g/90/90" />*/}
|
||||||
|
<span className={icons.user} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.authInfoTitle}>
|
||||||
|
<Message {...messages.youAuthorizedAs} />
|
||||||
|
</div>
|
||||||
|
<div className={styles.authInfoEmail}>
|
||||||
|
erickskrauch@yandex.ru
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</PanelBodyHeader>
|
||||||
|
<div className={styles.permissionsContainer}>
|
||||||
|
<div className={styles.permissionsTitle}>
|
||||||
|
<Message {...messages.theAppNeedsAccess} />
|
||||||
|
</div>
|
||||||
|
<ul className={styles.permissionsList}>
|
||||||
|
<li>Authorization for Minecraft servers</li>
|
||||||
|
<li>Manage your skins directory and additional rows for multiline</li>
|
||||||
|
<li>Change the active skin</li>
|
||||||
|
<li>View your E-mail address</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
Footer: () => (
|
||||||
|
<button className={buttons.green}>
|
||||||
|
<Message {...messages.approve} />
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
Links: () => (
|
||||||
|
<a href="#">
|
||||||
|
<Message {...messages.decline} />
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class _Permissions extends Component {
|
||||||
displayName = 'Permissions';
|
displayName = 'Permissions';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -11,7 +11,49 @@ import {helpLinks as helpLinksStyles} from './helpLinks.scss';
|
|||||||
import messages from './Register.messages';
|
import messages from './Register.messages';
|
||||||
import activationMessages from './Activation.messages';
|
import activationMessages from './Activation.messages';
|
||||||
|
|
||||||
export default class Register extends Component {
|
export default function Register() {
|
||||||
|
return {
|
||||||
|
Title: () => ( // TODO: separate component for PageTitle
|
||||||
|
<Message {...messages.registerTitle}>
|
||||||
|
{(msg) => <span>{msg}<Helmet title={msg} /></span>}
|
||||||
|
</Message>
|
||||||
|
),
|
||||||
|
Body: () => (
|
||||||
|
<div>
|
||||||
|
<Input icon="user" color="blue" type="text" placeholder={messages.yourNickname} />
|
||||||
|
<Input icon="envelope" color="blue" type="email" placeholder={messages.yourEmail} />
|
||||||
|
<Input icon="key" color="blue" type="password" placeholder={messages.accountPassword} />
|
||||||
|
<Input icon="key" color="blue" type="password" placeholder={messages.repeatPassword} />
|
||||||
|
|
||||||
|
<Checkbox color="blue" label={
|
||||||
|
<Message {...messages.acceptRules} values={{
|
||||||
|
link: (
|
||||||
|
<a href="#">
|
||||||
|
<Message {...messages.termsOfService} />
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
}} />
|
||||||
|
} />
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
Footer: (props) => (
|
||||||
|
<button className={buttons.blue} onClick={(event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
props.history.push('/activation');
|
||||||
|
}}>
|
||||||
|
<Message {...messages.signUpButton} />
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
Links: () => (
|
||||||
|
<a href="#">
|
||||||
|
<Message {...activationMessages.didNotReceivedEmail} />
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class _Register extends Component {
|
||||||
displayName = 'Register';
|
displayName = 'Register';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -65,6 +65,10 @@ $bodyTopBottomPadding: 15px;
|
|||||||
> * {
|
> * {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button { // TODO: добавленно временно, пока не устаканится лейаут панелек
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bodyHeader {
|
.bodyHeader {
|
||||||
|
@ -15,6 +15,9 @@ export default class Userbar extends Component {
|
|||||||
<Link to="/register" className={buttons.blue}>
|
<Link to="/register" className={buttons.blue}>
|
||||||
<Message {...messages.register} />
|
<Message {...messages.register} />
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link to="/oauth/permissions" className={buttons.blue}>
|
||||||
|
Test oAuth
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { TransitionMotion, spring } from 'react-motion';
|
|
||||||
|
|
||||||
import AppInfo from 'components/auth/AppInfo';
|
import AppInfo from 'components/auth/AppInfo';
|
||||||
|
import PanelTransition from 'components/auth/PanelTransition';
|
||||||
|
|
||||||
import styles from './auth.scss';
|
import styles from './auth.scss';
|
||||||
|
|
||||||
const springConfig = [200, 20];
|
|
||||||
|
|
||||||
class AuthPage extends Component {
|
class AuthPage extends Component {
|
||||||
displayName = 'AuthPage';
|
displayName = 'AuthPage';
|
||||||
|
|
||||||
@ -18,320 +15,17 @@ class AuthPage extends Component {
|
|||||||
description: `Лучший альтернативный лаунчер для Minecraft с большим количеством версий и их модификаций, а также возмоностью входа как с лицензионным аккаунтом, так и без него.`
|
description: `Лучший альтернативный лаунчер для Minecraft с большим количеством версий и их модификаций, а также возмоностью входа как с лицензионным аккаунтом, так и без него.`
|
||||||
};
|
};
|
||||||
|
|
||||||
var { path, children } = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.sidebar}>
|
<div className={styles.sidebar}>
|
||||||
<AppInfo {...appInfo} />
|
<AppInfo {...appInfo} />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<TransitionMotion
|
<PanelTransition {...this.props} />
|
||||||
willEnter={this.willEnter}
|
|
||||||
willLeave={this.willLeave}
|
|
||||||
styles={{
|
|
||||||
[path]: {
|
|
||||||
children,
|
|
||||||
x: spring(0, springConfig)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{(items) => (
|
|
||||||
<div style={{position: 'relative', overflow: 'hidden', width: '100%', height: '500px'}}>
|
|
||||||
{Object.keys(items).map((path) => {
|
|
||||||
const {children, x} = items[path];
|
|
||||||
|
|
||||||
const style = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: '100%',
|
|
||||||
transform: `translateX(${x}%)`
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div key={path} style={style}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</TransitionMotion>
|
|
||||||
<TheDemo />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
willEnter(key, styles) {
|
|
||||||
return {
|
|
||||||
...styles,
|
|
||||||
x: spring(100, springConfig)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
willLeave(key, styles) {
|
|
||||||
return {
|
|
||||||
...styles,
|
|
||||||
x: spring(-100, springConfig)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
import { FormattedMessage as Message } from 'react-intl';
|
|
||||||
import Helmet from 'react-helmet';
|
|
||||||
import ReactHeight from 'react-height';
|
|
||||||
|
|
||||||
import panelStyles from 'components/ui/panel.scss';
|
|
||||||
import buttons from 'components/ui/buttons.scss';
|
|
||||||
import icons from 'components/ui/icons.scss';
|
|
||||||
import { Panel, PanelBody, PanelFooter, PanelHeader } from 'components/ui/Panel';
|
|
||||||
import { Input, Checkbox } from 'components/ui/Form';
|
|
||||||
|
|
||||||
import messages from 'components/auth/Login.messages';
|
|
||||||
import regMessages from 'components/auth/Register.messages';
|
|
||||||
import {helpLinks as helpLinksStyles} from 'components/auth/helpLinks.scss';
|
|
||||||
import passwordMessages from 'components/auth/Password.messages';
|
|
||||||
|
|
||||||
const opacitySpringConfig = [200, 20];
|
|
||||||
const heightSpringConfig = [200, 18];
|
|
||||||
const transformSpringConfig = [500, 20];
|
|
||||||
|
|
||||||
// TODO: сделать более быстрый фейд на горизонтальном скролле
|
|
||||||
|
|
||||||
class TheDemo extends Component {
|
|
||||||
state = {
|
|
||||||
isFirstPage: true,
|
|
||||||
height: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
var {isFirstPage} = this.state;
|
|
||||||
|
|
||||||
var path = `page${isFirstPage ? '1' : '2'}`;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<TransitionMotion
|
|
||||||
styles={{
|
|
||||||
[path]: {
|
|
||||||
isFirstPage,
|
|
||||||
transformSpring: spring(0),
|
|
||||||
opacitySpring: spring(1)
|
|
||||||
},
|
|
||||||
common: {
|
|
||||||
heightSpring: spring(this.state.height[path] || 0, heightSpringConfig)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
willEnter={this.willEnter}
|
|
||||||
willLeave={this.willLeave}
|
|
||||||
>
|
|
||||||
{(items) => {
|
|
||||||
var keys = Object.keys(items).filter((key) => key !== 'common');
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Panel>
|
|
||||||
<PanelHeader>
|
|
||||||
<div style={{
|
|
||||||
position: 'relative',
|
|
||||||
height: '59px',
|
|
||||||
overflow: 'hidden'
|
|
||||||
}}>
|
|
||||||
{keys.map((key) => this.getHeader(key, items[key]))}
|
|
||||||
</div>
|
|
||||||
</PanelHeader>
|
|
||||||
<PanelBody style={{
|
|
||||||
overflow: 'hidden'
|
|
||||||
}}>
|
|
||||||
<div style={{
|
|
||||||
position: 'relative',
|
|
||||||
height: `${items.common.heightSpring}px`
|
|
||||||
}}>
|
|
||||||
{keys.map((key) => this.getBody(key, items[key]))}
|
|
||||||
</div>
|
|
||||||
</PanelBody>
|
|
||||||
<PanelFooter>
|
|
||||||
<div style={{
|
|
||||||
position: 'relative',
|
|
||||||
height: '50px',
|
|
||||||
overflow: 'hidden'
|
|
||||||
}}>
|
|
||||||
{keys.map((key) => this.getFooter(key, items[key]))}
|
|
||||||
</div>
|
|
||||||
</PanelFooter>
|
|
||||||
</Panel>
|
|
||||||
<div className={helpLinksStyles} style={{position: 'relative', height: '20px'}}>
|
|
||||||
{keys.map((key) => this.getLinks(key, items[key]))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</TransitionMotion>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
willEnter = (key, styles) => {
|
|
||||||
var sign = this.state.isFirstPage ? -1 : 1;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...styles,
|
|
||||||
transformSpring: spring(sign * 100, transformSpringConfig),
|
|
||||||
opacitySpring: spring(1, opacitySpringConfig)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
willLeave = (key, styles) => {
|
|
||||||
var sign = this.state.isFirstPage ? -1 : 1;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...styles,
|
|
||||||
transformSpring: spring(sign * -100, transformSpringConfig),
|
|
||||||
opacitySpring: spring(0, opacitySpringConfig)
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
getBody(key, props) {
|
|
||||||
var {isFirstPage, transformSpring, opacitySpring} = props;
|
|
||||||
|
|
||||||
var style = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: '100%',
|
|
||||||
WebkitTransform: `translateX(${transformSpring}%)`,
|
|
||||||
transform: `translateX(${transformSpring}%)`,
|
|
||||||
opacity: opacitySpring
|
|
||||||
};
|
|
||||||
|
|
||||||
return (isFirstPage ? (
|
|
||||||
<ReactHeight key={`body${key}`} style={style} onHeightReady={this.updateHeight}>
|
|
||||||
<Input icon="envelope" type="email" placeholder={messages.emailOrUsername} />
|
|
||||||
</ReactHeight>
|
|
||||||
) : (
|
|
||||||
<ReactHeight key={`body${key}`} style={style} onHeightReady={this.updateHeight}>
|
|
||||||
<Input icon="user" color="blue" type="text" placeholder={regMessages.yourNickname} />
|
|
||||||
<Input icon="envelope" color="blue" type="email" placeholder={regMessages.yourEmail} />
|
|
||||||
<Input icon="key" color="blue" type="password" placeholder={regMessages.accountPassword} />
|
|
||||||
<Input icon="key" color="blue" type="password" placeholder={regMessages.repeatPassword} />
|
|
||||||
|
|
||||||
<Checkbox color="blue" label={
|
|
||||||
<Message {...regMessages.acceptRules} values={{
|
|
||||||
link: (
|
|
||||||
<a href="#">
|
|
||||||
<Message {...regMessages.termsOfService} />
|
|
||||||
</a>
|
|
||||||
)
|
|
||||||
}} />
|
|
||||||
} />
|
|
||||||
</ReactHeight>
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
updateHeight = (height) => {
|
|
||||||
this.setState({
|
|
||||||
height: {
|
|
||||||
...this.state.height,
|
|
||||||
[`page${this.state.isFirstPage ? '1' : '2'}`]: height
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
getFooter(key, props) {
|
|
||||||
var {isFirstPage, opacitySpring} = props;
|
|
||||||
|
|
||||||
var style = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: '100%',
|
|
||||||
opacity: opacitySpring
|
|
||||||
};
|
|
||||||
|
|
||||||
return (isFirstPage ? (
|
|
||||||
<button key={`footer${key}`} style={style} onClick={this.onSwitchViews} className={buttons.green}>
|
|
||||||
<Message {...messages.next} />
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<button key={`footer${key}`} style={style} onClick={this.onSwitchViews} className={buttons.blue}>
|
|
||||||
<Message {...regMessages.signUpButton} />
|
|
||||||
</button>
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
getHeader(key, props) {
|
|
||||||
var {isFirstPage, transformSpring} = props;
|
|
||||||
|
|
||||||
var style = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: '100%'
|
|
||||||
};
|
|
||||||
|
|
||||||
var scrollStyle = {
|
|
||||||
WebkitTransform: `translateY(${transformSpring}%)`,
|
|
||||||
transform: `translateY(${transformSpring}%)`
|
|
||||||
};
|
|
||||||
|
|
||||||
var sideScrollStyle = {
|
|
||||||
position: 'relative',
|
|
||||||
zIndex: 2,
|
|
||||||
WebkitTransform: `translateX(${-Math.abs(transformSpring)}%)`,
|
|
||||||
transform: `translateX(${-Math.abs(transformSpring)}%)`
|
|
||||||
};
|
|
||||||
|
|
||||||
return (isFirstPage ? (
|
|
||||||
<div key={`header${key}`} style={style}>
|
|
||||||
<Message {...messages.loginTitle}>
|
|
||||||
{(msg) => <div style={scrollStyle}>{msg}<Helmet title={msg} /></div>}
|
|
||||||
</Message>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div key={`header${key}`} style={style}>
|
|
||||||
<button style={sideScrollStyle} onClick={this.onSwitchViews} className={panelStyles.headerControl}>
|
|
||||||
<span className={icons.arrowLeft} />
|
|
||||||
</button>
|
|
||||||
<Message {...regMessages.registerTitle}>
|
|
||||||
{(msg) => <div style={scrollStyle}>{msg}<Helmet title={msg} /></div>}
|
|
||||||
</Message>
|
|
||||||
</div>
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
getLinks(key, props) {
|
|
||||||
var {isFirstPage, opacitySpring} = props;
|
|
||||||
|
|
||||||
var style = {
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
width: '100%',
|
|
||||||
opacity: opacitySpring
|
|
||||||
};
|
|
||||||
|
|
||||||
return (isFirstPage ? (
|
|
||||||
<div key={`links${key}`} style={style}>
|
|
||||||
<a href="#">
|
|
||||||
<Message {...passwordMessages.forgotPassword} />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div key={`links${key}`} style={style}>
|
|
||||||
<a href="#">
|
|
||||||
{'test 123'}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
onSwitchViews = (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
isFirstPage: !this.state.isFirstPage
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect((state) => ({
|
export default connect((state) => ({
|
||||||
|
@ -27,11 +27,11 @@ export default (
|
|||||||
<IndexRoute component={IndexPage} onEnter={requireAuth} />
|
<IndexRoute component={IndexPage} onEnter={requireAuth} />
|
||||||
|
|
||||||
<Route path="auth" component={AuthPage}>
|
<Route path="auth" component={AuthPage}>
|
||||||
<Route path="/login" component={Login} />
|
<Route path="/login" components={new Login()} />
|
||||||
<Route path="/password" component={Password} />
|
<Route path="/password" components={new Password()} />
|
||||||
<Route path="/register" component={Register} />
|
<Route path="/register" components={new Register()} />
|
||||||
<Route path="/activation" component={Activation} />
|
<Route path="/activation" components={new Activation()} />
|
||||||
<Route path="/oauth/permissions" component={Permissions} />
|
<Route path="/oauth/permissions" components={new Permissions()} />
|
||||||
<Route path="/oauth/:id" component={Permissions} />
|
<Route path="/oauth/:id" component={Permissions} />
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
|
Loading…
Reference in New Issue
Block a user