Промежуточный этап верстки форм

This commit is contained in:
SleepWalker 2016-01-08 15:14:35 +02:00
parent 900dac850e
commit 54fff54135
12 changed files with 633 additions and 24 deletions

View File

@ -1,12 +1,252 @@
import React, { Component } from 'react';
import { FormattedMessage as Message } from 'react-intl';
import classNames from 'classnames';
import buttons from 'components/ui/buttons.scss';
import icons from 'components/ui/icons.scss';
import { Panel, PanelHeader, PanelBody, PanelFooter } from 'components/ui/Panel';
import { Input } from 'components/ui/Form';
import styles from './signIn.scss';
import messages from './SignIn.messages';
import panel from 'components/ui/panel.scss';
styles.headerControl = panel.headerControl;
// 0.5s cubic-bezier(0.075, 0.82, 0.165, 1)
/**
* Forms:
* Register
* - RegisterForm
* - ConfirmRegister
*
* SignIn
* - Email
* - Password
* - Permissions
*/
export default class SignIn extends Component {
displayName = 'SignIn';
render() {
return (
<div>
Hello World
<div className={styles.signIn}>
<Panel title={<Message {...messages.signInTitle} />}>
<PanelBody>
<Input icon="envelope" type="email" placeholder="E-mail" />
</PanelBody>
<PanelFooter>
<button className={buttons.green}>
<Message {...messages.next} />
</button>
</PanelFooter>
</Panel>
<div className={styles.helpLinks}>
<a href="#">
<Message {...messages.forgotPassword} />
</a>
{' | '}
<a href="#">
<Message {...messages.contactSupport} />
</a>
</div>
</div>
<div className={styles.signIn}>
<Panel>
<PanelHeader>
<div className={styles.headerControl}>
<button className={buttons.black}>
<span className={icons.arrowLeft} />
</button>
</div>
<Message {...messages.enterPassword} />
</PanelHeader>
<PanelBody>
<div className={styles.error}>
<Message {...messages.invalidPassword} />
<br/>
<Message {...messages.suggestResetPassword} values={{
link: (
<a href="#">
<Message {...messages.forgotYourPassword} />
</a>
)
}} />
</div>
<div className={styles.miniProfile}>
<div className={styles.avatar}>
<img src="//lorempixel.com/g/90/90" />
</div>
<div className={styles.email}>
erickskrauch@yandex.ru
</div>
</div>
<div className={styles.formIconRow}>
<Input icon="key" type="password" placeholder="Account password" />
</div>
<div className={styles.checkboxRow}>
<label>
<input type="checkbox" />
<Message {...messages.rememberMe} />
</label>
</div>
</PanelBody>
<PanelFooter>
<button className={buttons.green}>
<Message {...messages.signInButton} />
</button>
</PanelFooter>
</Panel>
<div className={styles.helpLinks}>
<a href="#">
<Message {...messages.forgotPassword} />
</a>
{' | '}
<a href="#">
<Message {...messages.contactSupport} />
</a>
</div>
</div>
<div className={styles.signIn}>
<Panel title={<Message {...messages.permissionsTitle} />}>
<PanelBody>
<div className={styles.authInfo}>
<div className={styles.avatar}>
<img src="//lorempixel.com/g/90/90" />
</div>
<div className={styles.email}>
<Message {...messages.youAuthorizedAs} />
</div>
<div className={styles.email}>
erickskrauch@yandex.ru
</div>
</div>
<div className={styles.disclaimer}>
<Message {...messages.theAppNeedsAccess} />
</div>
<ul className={styles.permissionsList}>
<li>
one two three
</li>
<li>
one two three
</li>
<li>
one two three
</li>
<li>
one two three
</li>
</ul>
</PanelBody>
<PanelFooter>
<button className={classNames(buttons.black, styles.decline)}>
<Message {...messages.decline} />
</button>
<button className={buttons.green}>
<Message {...messages.approve} />
</button>
</PanelFooter>
</Panel>
<div className={styles.helpLinks}>
<a href="#">
<Message {...messages.contactSupport} />
</a>
</div>
</div>
<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>
<div className={styles.checkboxRow}>
<label>
<input type="checkbox" />
<Message {...messages.acceptRules} values={{
link: (
<a href="#">
<Message {...messages.termsOfService} />
</a>
)
}} />
</label>
</div>
</PanelBody>
<PanelFooter>
<button className={buttons.blue}>
<Message {...messages.signUpButton} />
</button>
</PanelFooter>
</Panel>
<div className={styles.helpLinks}>
<a href="#">
<Message {...messages.contactSupport} />
</a>
</div>
</div>
<div className={styles.signIn}>
<Panel>
<PanelHeader>
<div className={styles.headerControl}>
<button className={buttons.black}>
<span className={icons.arrowLeft} />
</button>
</div>
<Message {...messages.accountActivationTitle} />
</PanelHeader>
<PanelBody>
<div className={styles.description}>
<div className={styles.descriptionImage}>
<span className={icons.envelope} />
</div>
<div className={styles.descriptionText}>
<Message {...messages.activationMailWasSent} values={{
email: (<b>erickskrauch@yandex.ru</b>)
}} />
</div>
</div>
<div className={styles.formRow}>
{/* TODO: E-mail i18n*/}
<Input type="email" placeholder="Enter the code from E-mail here" />
</div>
</PanelBody>
<PanelFooter>
<button className={buttons.blue}>
<Message {...messages.confirmEmail} />
</button>
</PanelFooter>
</Panel>
<div className={styles.helpLinks}>
<a href="#">
<Message {...messages.didNotReceivedEmail} />
</a>
{' | '}
<a href="#">
<Message {...messages.contactSupport} />
</a>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,124 @@
import { defineMessages } from 'react-intl';
export default defineMessages({
signInTitle: {
id: 'signInTitle',
defaultMessage: 'Sign in'
},
next: {
id: 'next',
defaultMessage: 'Next'
},
enterPassword: {
id: 'enterPassword',
defaultMessage: 'Enter password'
},
rememberMe: {
id: 'rememberMe',
defaultMessage: 'Remember me on this device'
},
signInButton: {
id: 'signInButton',
defaultMessage: 'Sign in'
},
invalidPassword: {
id: 'invalidPassword',
defaultMessage: 'You entered wrong account password.'
},
suggestResetPassword: {
id: 'suggestResetPassword',
defaultMessage: 'Are you have {link}?'
},
forgotYourPassword: {
id: 'forgotYourPassword',
defaultMessage: 'forgot your password'
},
forgotPassword: {
id: 'forgotPassword',
defaultMessage: 'Forgot password'
},
contactSupport: {
id: 'contactSupport',
defaultMessage: 'Contact support'
},
permissionsTitle: {
id: 'permissionsTitle',
defaultMessage: 'Application permissions'
},
youAuthorizedAs: {
id: 'youAuthorizedAs',
defaultMessage: 'You authorized as:'
},
theAppNeedsAccess: {
id: 'theAppNeedsAccess',
defaultMessage: 'This applications needs access to your data'
},
decline: {
id: 'decline',
defaultMessage: 'Decline'
},
approve: {
id: 'approve',
defaultMessage: 'Approve'
},
signUpTitle: {
id: 'signUpTitle',
defaultMessage: 'Sign Up'
},
signUpButton: {
id: 'signUpButton',
defaultMessage: 'Register'
},
acceptRules: {
id: 'acceptRules',
defaultMessage: 'I agree with {link}'
},
termsOfService: {
id: 'termsOfService',
defaultMessage: 'Terms of service'
},
accountActivationTitle: {
id: 'accountActivationTitle',
defaultMessage: 'Account activation'
},
activationMailWasSent: {
id: 'activationMailWasSent',
defaultMessage: 'Please check {email} for the message with the last registration step'
},
confirmEmail: {
id: 'confirmEmail',
defaultMessage: 'Confirm E-mail'
},
didNotReceivedEmail: {
id: 'didNotReceivedEmail',
defaultMessage: 'Did not received E-mail?'
},
});

View File

@ -0,0 +1,31 @@
@import '~components/ui/colors.scss';
.signIn {
margin-bottom: 10px;
}
.decline {
border-top: 1px solid lighter($black);
width: 42%;
flex-grow: 0;
}
.helpLinks {
margin: 8px 0;
color: #444;
text-align: center;
font-size: 16px;
a {
color: #444;
border-bottom: 1px dotted #444;
text-decoration: none;
transition: .25s;
&:hover {
border-bottom-color: #777;
color: #777;
}
}
}

View File

@ -0,0 +1,29 @@
import React from 'react';
import classNames from 'classnames';
import icons from './icons.scss';
import styles from './form.scss';
export function Input(props) {
props = {
type: 'text',
...props
};
var baseClass = styles.formRow;
var icon;
if (props.icon) {
baseClass = styles.formIconRow;
icon = (
<div className={classNames(styles.formFieldIcon, icons[props.icon])} />
);
}
return (
<div className={baseClass}>
<input className={styles.textField} {...props} />
{icon}
</div>
);
}

View File

@ -0,0 +1,47 @@
import React from 'react';
import styles from './panel.scss';
export function Panel(props) {
var { title } = props;
if (title) {
title = (
<PanelHeader>
{title}
</PanelHeader>
);
}
return (
<div className={styles.panel}>
{title}
{props.children}
</div>
);
}
export function PanelHeader(props) {
return (
<div className={styles.header}>
{props.children}
</div>
);
}
export function PanelBody(props) {
return (
<div className={styles.body}>
{props.children}
</div>
);
}
export function PanelFooter(props) {
return (
<div className={styles.footer}>
{props.children}
</div>
);
}

View File

@ -21,16 +21,20 @@
}
}
.button {
.button,
.black {
display: inline-block;
box-sizing: border-box;
height: 50px;
padding: 0 15px;
border: none;
font-family: $font-family-title;
color: $defaultButtonTextColor;
font-size: 18px;
line-height: 50px;
text-decoration: none;
cursor: pointer;
transition: background-color 0.25s;
@ -46,3 +50,4 @@
}
@include button-color('blue', $blue);
@include button-color('green', $green);

View File

@ -0,0 +1,76 @@
@import '~components/ui/colors.scss';
@import '~components/ui/fonts.scss';
.formRow {
position: relative;
height: 50px;
max-width: 100%;
margin: 10px 0;
}
.formIconRow {
composes: formRow;
.textField {
padding-left: 60px;
}
}
.textField {
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 50px;
width: 100%;
border: 2px solid lighter($black);
background: $black;
font-size: 20px;
color: #aaa;
font-family: $font-family-base;
padding: 0 10px;
transition: border-color .25s;
&::placeholder {
opacity: 1;
color: #444;
}
&:hover {
border-color: #aaa;
~ .formFieldIcon {
border-color: #aaa;
}
}
&:focus {
border-color: $green;
color: #fff;
~ .formFieldIcon {
background: $green;
border-color: $green;
color: #fff;
}
}
}
.formFieldIcon {
box-sizing: border-box;
position: absolute;
height: 50px;
width: 50px;
line-height: 46px;
text-align: center;
border: 2px solid lighter($black);
color: #444;
transition: border-color .25s;
}

View File

@ -0,0 +1,56 @@
@import '~components/ui/colors.scss';
@import '~components/ui/fonts.scss';
.panel {
background: $black;
}
.header {
box-sizing: border-box;
height: 50px;
border-bottom: 1px solid lighter($black);
font-family: $font-family-title;
text-align: center;
line-height: 48px;
font-size: 20px;
color: #fff;
}
.headerControl {
float: left;
line-height: 1;
border-right: 1px solid lighter($black);
overflow: hidden;
height: 49px;
}
.body {
padding: 15px;
color: #ccc;
font-size: 18px;
b {
color: #fff;
}
a {
color: #fff;
border-bottom: 1px dotted #ede9e2;
text-decoration: none;
transition: .25s;
&:hover {
border-bottom-color: #ccc;
color: #ccc;
}
}
}
.footer {
display: flex;
> * {
flex-grow: 1;
}
}

View File

@ -5,13 +5,17 @@
.{{baseClass}} {
line-height: 1;
vertical-align: middle;
display: inline-block;
speak: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.{{baseClass}}:before {
font-family: {{fontName}} !important;
font-style: normal;
font-weight: normal !important;
vertical-align: top;
}
{{#each codepoints}}

View File

@ -1,3 +1,6 @@
@import '~components/ui/colors.scss';
@import '~components/ui/fonts.scss';
html,
body,
:global(.app) {
@ -6,6 +9,11 @@ body,
padding: 0;
}
body {
font-family: $font-family-base;
background: $light;
}
a {
text-decoration: none;
}

View File

@ -2,7 +2,7 @@
.sidebar {
position: absolute;
top: 0;
top: 50px;
bottom: 0;
left: 0;
width: 300px;
@ -12,4 +12,5 @@
.content {
margin-left: 300px;
padding: 55px 50px;
}

View File

@ -2,8 +2,7 @@
@import '~components/ui/fonts.scss';
.root {
background: $light;
min-height: 100%;
height: 100%;
}
.wrapper {
@ -12,6 +11,7 @@
}
.header {
position: relative;
height: 50px;
background: $green;
}
@ -33,25 +33,13 @@
.body {
composes: wrapper;
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 0;
}
position: relative;
.sidebar {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 300px;
background: $black;
}
.content {
margin-left: 300px;
// place for header
min-height: 100%;
box-sizing: border-box;
padding-top: 50px;
margin-top: -50px;
}
.userbar {