Второй слайд формы авторизации

This commit is contained in:
SleepWalker 2016-01-09 15:51:55 +02:00
parent dbe933d2a5
commit a3cf38e458
7 changed files with 208 additions and 61 deletions

View File

@ -5,15 +5,13 @@ import classNames from 'classnames';
import buttons from 'components/ui/buttons.scss';
import icons from 'components/ui/icons.scss';
import { Panel, PanelBody, PanelFooter } from 'components/ui/Panel';
import { Input } from 'components/ui/Form';
import { Panel, PanelBody, PanelFooter, PanelError } from 'components/ui/Panel';
import { Input, Checkbox } from 'components/ui/Form';
import styles from './signIn.scss';
import messages from './SignIn.messages';
import panel from 'components/ui/panel.scss';
// 0.5s cubic-bezier(0.075, 0.82, 0.165, 1)
/**
@ -58,35 +56,31 @@ export default class SignIn extends Component {
<div className={styles.signIn}>
<Panel icon="arrowLeft" title={<Message {...messages.enterPassword} />}>
<PanelBody>
<div className={styles.error}>
<Message {...messages.invalidPassword} />
<br/>
<Message {...messages.suggestResetPassword} values={{
link: (
<a href="#">
<Message {...messages.forgotYourPassword} />
</a>
)
}} />
</div>
<PanelError message={
<span>
<Message {...messages.invalidPassword} />
<br/>
<Message {...messages.suggestResetPassword} values={{
link: (
<a href="#">
<Message {...messages.forgotYourPassword} />
</a>
)
}} />
</span>
} />
<div className={styles.miniProfile}>
<div className={styles.avatar}>
<img src="//lorempixel.com/g/90/90" />
{/*<img src="//lorempixel.com/g/90/90" />*/}
<span className={icons.user} />
</div>
<div className={styles.email}>
erickskrauch@yandex.ru
</div>
</div>
<div className={styles.formIconRow}>
<Input icon="key" type="password" placeholder="Account password" />
</div>
<Input icon="key" type="password" placeholder="Account password" />
<div className={styles.checkboxRow}>
<label>
<input type="checkbox" />
<Message {...messages.rememberMe} />
</label>
</div>
<Checkbox label={<Message {...messages.rememberMe} />} />
</PanelBody>
<PanelFooter>
<button className={buttons.green}>
@ -154,35 +148,24 @@ export default class SignIn extends Component {
<div className={styles.signIn}>
<Panel title={<Message {...messages.signUpTitle} />}>
<PanelBody>
<div className={styles.formIconRow}>
{/* TODO: E-mail i18n*/}
<Input icon="user" type="text" placeholder="Your nickname" />
</div>
<div className={styles.formIconRow}>
{/* TODO: E-mail i18n*/}
<Input icon="envelope" type="email" placeholder="Your E-mail" />
</div>
<div className={styles.formIconRow}>
{/* TODO: Account password i18n*/}
<Input icon="key" type="password" placeholder="Account password" />
</div>
<div className={styles.formIconRow}>
{/* TODO: Account password i18n*/}
<Input icon="key" type="password" placeholder="Repeat password" />
</div>
{/* TODO: E-mail i18n*/}
<Input icon="user" type="text" placeholder="Your nickname" />
{/* TODO: E-mail i18n*/}
<Input icon="envelope" type="email" placeholder="Your E-mail" />
{/* TODO: Account password i18n*/}
<Input icon="key" type="password" placeholder="Account password" />
{/* TODO: Account password i18n*/}
<Input icon="key" type="password" placeholder="Repeat password" />
<div className={styles.checkboxRow}>
<label>
<input type="checkbox" />
<Message {...messages.acceptRules} values={{
link: (
<a href="#">
<Message {...messages.termsOfService} />
</a>
)
}} />
</label>
</div>
<Checkbox label={
<Message {...messages.acceptRules} values={{
link: (
<a href="#">
<Message {...messages.termsOfService} />
</a>
)
}} />
} />
</PanelBody>
<PanelFooter>
<button className={buttons.blue}>

View File

@ -2,6 +2,7 @@
.signIn {
margin-bottom: 10px;
text-align: center;
}
.decline {
@ -29,3 +30,25 @@
}
}
}
@import '~components/ui/fonts.scss';
.avatar {
width: 90px;
height: 90px;
font-size: 90px;
line-height: 90px;
margin: 0 auto;
img {
width: 100%;
}
}
.email {
font-family: $font-family-title;
font-size: 18px;
color: #fff;
margin-bottom: 15px;
margin-top: 10px;
}

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { Component } from 'react';
import classNames from 'classnames';
@ -27,3 +27,21 @@ export function Input(props) {
</div>
);
}
export class Checkbox extends Component {
displayName = 'Checkbox';
render() {
var { label } = this.props;
return (
<div className={styles.checkboxRow}>
<label className={styles.checkboxContainer}>
<input className={styles.checkboxInput} type="checkbox" />
<div className={styles.checkbox} />
{label}
</label>
</div>
);
}
}

View File

@ -55,3 +55,14 @@ export function PanelFooter(props) {
</div>
);
}
export function PanelError(props) {
var { message } = props;
return (
<div className={styles.error}>
<span className={styles.close} />
{message}
</div>
);
}

View File

@ -1,6 +1,15 @@
@import '~components/ui/colors.scss';
@import '~components/ui/fonts.scss';
@mixin form-transition() {
// Анимация фона должна быть быстрее анимации рамки, т.к. визуально фон заполняется медленнее
transition: border-color .25s,
background-color .20s;
}
/**
* Input
*/
.formRow {
position: relative;
height: 50px;
@ -66,6 +75,8 @@
.formFieldIcon {
box-sizing: border-box;
position: absolute;
left: 0;
top: 0;
height: 50px;
width: 50px;
line-height: 46px;
@ -73,7 +84,77 @@
border: 2px solid lighter($black);
color: #444;
// Анимация фона должна быть быстрее анимации рамки, т.к. визуально фон заполняется медленнее
transition: border-color .25s,
background-color .20s;
@include form-transition();
}
/**
* Checkbox
*/
.checkboxRow {
height: 22px;
margin-top: 15px;
}
.checkboxContainer {
display: inline-block;
position: relative;
padding-left: 27px;
font-family: $font-family-title;
font-size: 16px;
line-height: 24px;
color: #fff;
cursor: pointer;
&:hover {
.checkbox {
border-color: $green;
}
}
}
.checkboxPosition {
position: absolute;
box-sizing: border-box;
left: 0;
top: 0;
margin: 0;
width: 22px;
height: 22px;
}
.checkboxInput {
composes: checkboxPosition;
opacity: 0;
&:checked {
+ .checkbox {
background: $green;
border-color: $green;
&:before {
opacity: 1;
}
}
}
}
.checkbox {
composes: checkboxPosition;
composes: checkmark from './icons.scss';
border: 2px #fff solid;
font-size: 10px;
line-height: 18px;
@include form-transition();
&:before {
opacity: 0;
transition: opacity 0.3s;
}
}

View File

@ -12,7 +12,7 @@
font-family: $font-family-title;
text-align: center;
line-height: 48px;
line-height: 50px;
font-size: 20px;
color: #fff;
}
@ -60,3 +60,29 @@
flex-grow: 1;
}
}
.error {
position: relative;
padding: 10px;
margin: -15px;
margin-bottom: 15px;
background: #e66c69;
border: 1px #e15457 solid;
font-size: 14px;
line-height: 1.3;
color: #fff;
}
.close {
composes: close from './icons.scss';
position: absolute;
right: 5px;
top: 5px;
font-size: 10px;
cursor: pointer;
}

View File

@ -27,7 +27,7 @@ var isTest = process.argv.some(function(arg) {
});
const API_HOST = 'http://account.l';
const CSS_CLASS_TEMPLATE = isProduction ? '[hash:base64]' : '[path][name]-[local]';
const CSS_CLASS_TEMPLATE = isProduction ? '[hash:base64:5]' : '[path][name]-[local]';
var webpackConfig = {
entry: {
@ -131,7 +131,7 @@ var webpackConfig = {
postcss: [
cssnano({
sourcemap: !isProduction,
// sourcemap: !isProduction,
autoprefixer: {
add: true,
remove: true,
@ -153,7 +153,12 @@ if (isProduction) {
webpackConfig.module.loaders.forEach((loader) => {
if (loader.extractInProduction) {
var parts = loader.loader.split('!');
loader.loader = ExtractTextPlugin.extract(parts[0], parts.slice(1).join('!'));
loader.loader = ExtractTextPlugin.extract(
parts[0],
parts.slice(1)
.join('!')
.replace(/[&?]sourcemap/, '')
);
}
});