diff --git a/client/modules/App/App.jsx b/client/modules/App/App.jsx index 5598225d..b300cde0 100644 --- a/client/modules/App/App.jsx +++ b/client/modules/App/App.jsx @@ -1,6 +1,7 @@ import React, { PropTypes } from 'react'; import { connect } from 'react-redux'; import DevTools from './components/DevTools'; +import { setPreviousPath } from '../IDE/actions/ide'; class App extends React.Component { constructor(props, context) { @@ -12,6 +13,12 @@ class App extends React.Component { this.setState({ isMounted: true }); // eslint-disable-line react/no-did-mount-set-state } + componentWillReceiveProps(nextProps) { + if (nextProps.location !== this.props.location) { + this.props.setPreviousPath(this.props.location.pathname); + } + } + render() { return (
@@ -23,7 +30,11 @@ class App extends React.Component { } App.propTypes = { - children: PropTypes.object + children: PropTypes.object, + location: PropTypes.shape({ + pathname: PropTypes.string + }), + setPreviousPath: PropTypes.func.isRequired, }; -export default connect()(App); +export default connect(() => ({}), { setPreviousPath })(App); diff --git a/client/modules/IDE/components/LoginView.jsx b/client/modules/IDE/components/LoginView.jsx deleted file mode 100644 index 083c51b6..00000000 --- a/client/modules/IDE/components/LoginView.jsx +++ /dev/null @@ -1,63 +0,0 @@ -import React from 'react'; -import { reduxForm } from 'redux-form'; -import { validateAndLoginUser } from '../../User/actions'; -import LoginForm from '../components/LoginForm'; -// import GithubButton from '../components/GithubButton'; -import { Link } from 'react-router'; - - -class LoginView extends React.Component { - componentDidMount() { - this.refs.login.focus(); - } - - render() { - return ( -
-

Login

- - {/*

Or

- */} -

- Don't have an account?  - Sign Up -

-

- Forgot your password?  - Reset your password -

- Cancel -
- ); - } -} - -function mapStateToProps(state, ownProps) { - return { - user: state.user, - previousPath: ownProps.previousPath - }; -} - -function mapDispatchToProps() { - return { - validateAndLoginUser - }; -} - -function validate(formProps) { - const errors = {}; - if (!formProps.email) { - errors.email = 'Please enter an email'; - } - if (!formProps.password) { - errors.password = 'Please enter a password'; - } - return errors; -} - -export default reduxForm({ - form: 'login', - fields: ['email', 'password'], - validate -}, mapStateToProps, mapDispatchToProps)(LoginView); diff --git a/client/modules/IDE/pages/IDEView.jsx b/client/modules/IDE/pages/IDEView.jsx index 2b81ad60..3ad02193 100644 --- a/client/modules/IDE/pages/IDEView.jsx +++ b/client/modules/IDE/pages/IDEView.jsx @@ -28,8 +28,6 @@ import SplitPane from 'react-split-pane'; import Overlay from '../../App/components/Overlay'; import SketchList from '../components/SketchList'; import About from '../components/About'; -import LoginView from '../components/LoginView'; -import SignupView from '../components/SignupView'; import ResetPasswordView from '../components/ResetPasswordView'; import NewPasswordView from '../components/NewPasswordView'; @@ -434,24 +432,6 @@ class IDEView extends React.Component { ); } })()} - {(() => { // eslint-disable-line - if (this.props.location.pathname === '/login') { - return ( - - - - ); - } - })()} - {(() => { // eslint-disable-line - if (this.props.location.pathname === '/signup') { - return ( - - - - ); - } - })()} {(() => { // eslint-disable-line if (this.props.location.pathname === '/reset-password') { return ( diff --git a/client/modules/IDE/components/LoginForm.jsx b/client/modules/User/components/LoginForm.jsx similarity index 78% rename from client/modules/IDE/components/LoginForm.jsx rename to client/modules/User/components/LoginForm.jsx index 707396b1..b5a7aa67 100644 --- a/client/modules/IDE/components/LoginForm.jsx +++ b/client/modules/User/components/LoginForm.jsx @@ -5,27 +5,29 @@ function LoginForm(props) { const { fields: { email, password }, handleSubmit, submitting, pristine } = props; return (
-

+

+ {email.touched && email.error && {email.error}}

-

+

+ {password.touched && password.error && {password.error}}

- +
); } diff --git a/client/modules/IDE/components/SignupForm.jsx b/client/modules/User/components/SignupForm.jsx similarity index 73% rename from client/modules/IDE/components/SignupForm.jsx rename to client/modules/User/components/SignupForm.jsx index c4bfbaf3..07e6060b 100644 --- a/client/modules/IDE/components/SignupForm.jsx +++ b/client/modules/User/components/SignupForm.jsx @@ -5,42 +5,46 @@ function SignupForm(props) { const { fields: { username, email, password, confirmPassword }, handleSubmit, submitting, invalid, pristine } = props; return (
-

+

+ {username.touched && username.error && {username.error}}

-

+

+ {email.touched && email.error && {email.error}}

-

+

+ {password.touched && password.error && {password.error}}

-

+

+ {confirmPassword.touched && confirmPassword.error && {confirmPassword.error}} diff --git a/client/modules/User/pages/LoginView.jsx b/client/modules/User/pages/LoginView.jsx new file mode 100644 index 00000000..2cabbeef --- /dev/null +++ b/client/modules/User/pages/LoginView.jsx @@ -0,0 +1,89 @@ +import React, { PropTypes } from 'react'; +import { reduxForm } from 'redux-form'; +import { validateAndLoginUser } from '../actions'; +import LoginForm from '../components/LoginForm'; +// import GithubButton from '../components/GithubButton'; +import { Link, browserHistory } from 'react-router'; +import InlineSVG from 'react-inlinesvg'; +const exitUrl = require('../../../images/exit.svg'); +const logoUrl = require('../../../images/p5js-logo.svg'); + + +class LoginView extends React.Component { + constructor(props) { + super(props); + this.closeLoginPage = this.closeLoginPage.bind(this); + this.gotoHomePage = this.gotoHomePage.bind(this); + } + + closeLoginPage() { + browserHistory.push(this.props.previousPath); + } + + gotoHomePage() { + browserHistory.push('/'); + } + + render() { + return ( +

+
+ + +
+
+

Log In

+ + {/*

Or

+ */} +

+ Don't have an account?  + Sign Up +

+

+ Forgot your password?  + Reset your password +

+
+
+ ); + } +} + +function mapStateToProps(state) { + return { + user: state.user, + previousPath: state.ide.previousPath + }; +} + +function mapDispatchToProps() { + return { + validateAndLoginUser + }; +} + +function validate(formProps) { + const errors = {}; + if (!formProps.email) { + errors.email = 'Please enter an email'; + } + if (!formProps.password) { + errors.password = 'Please enter a password'; + } + return errors; +} + +LoginView.propTypes = { + previousPath: PropTypes.string.isRequired +}; + +export default reduxForm({ + form: 'login', + fields: ['email', 'password'], + validate +}, mapStateToProps, mapDispatchToProps)(LoginView); diff --git a/client/modules/IDE/components/SignupView.jsx b/client/modules/User/pages/SignupView.jsx similarity index 62% rename from client/modules/IDE/components/SignupView.jsx rename to client/modules/User/pages/SignupView.jsx index 30a97690..bd9877ee 100644 --- a/client/modules/IDE/components/SignupView.jsx +++ b/client/modules/User/pages/SignupView.jsx @@ -1,35 +1,57 @@ -import React from 'react'; +import React, { PropTypes } from 'react'; import { bindActionCreators } from 'redux'; -import * as UserActions from '../../User/actions'; +import * as UserActions from '../actions'; import { reduxForm } from 'redux-form'; import SignupForm from '../components/SignupForm'; import axios from 'axios'; -import { Link } from 'react-router'; +import { Link, browserHistory } from 'react-router'; +import InlineSVG from 'react-inlinesvg'; +const exitUrl = require('../../../images/exit.svg'); +const logoUrl = require('../../../images/p5js-logo.svg'); class SignupView extends React.Component { - componentDidMount() { - this.refs.signup.focus(); + constructor(props) { + super(props); + this.closeSignupPage = this.closeSignupPage.bind(this); + this.gotoHomePage = this.gotoHomePage.bind(this); + } + + closeSignupPage() { + browserHistory.push(this.props.previousPath); + } + + gotoHomePage() { + browserHistory.push('/'); } render() { return ( -
-

Sign Up

- -

- Already have an account?  - Login -

- Cancel +
+
+ + +
+
+

Sign Up

+ +

+ Already have an account?  + Log In +

+
); } } -function mapStateToProps(state, ownProps) { +function mapStateToProps(state) { return { user: state.user, - previousPath: ownProps.previousPath + previousPath: state.ide.previousPath }; } @@ -90,6 +112,10 @@ function onSubmitFail(errors) { console.log(errors); } +SignupView.propTypes = { + previousPath: PropTypes.string.isRequired +}; + export default reduxForm({ form: 'signup', fields: ['username', 'email', 'password', 'confirmPassword'], diff --git a/client/routes.jsx b/client/routes.jsx index a2e461f5..34e9b950 100644 --- a/client/routes.jsx +++ b/client/routes.jsx @@ -3,6 +3,8 @@ import React from 'react'; import App from './modules/App/App'; import IDEView from './modules/IDE/pages/IDEView'; import FullView from './modules/IDE/pages/FullView'; +import LoginView from './modules/User/pages/LoginView'; +import SignupView from './modules/User/pages/SignupView'; // import SketchListView from './modules/Sketch/pages/SketchListView'; import { getUser } from './modules/User/actions'; @@ -14,8 +16,8 @@ const routes = (store) => ( - - + + diff --git a/client/styles/abstracts/_placeholders.scss b/client/styles/abstracts/_placeholders.scss index 398dfc0c..23fa9b15 100644 --- a/client/styles/abstracts/_placeholders.scss +++ b/client/styles/abstracts/_placeholders.scss @@ -51,12 +51,19 @@ padding: 0; } +%none-themify-icon { + background-color: transparent; + border: none; + cursor: pointer; + padding: 0; +} + %button { @include themify() { background-color: getThemifyVariable('button-background-color'); color: getThemifyVariable('button-color'); cursor: pointer; - border: 1px solid getThemifyVariable('button-border-color'); + border: 2px solid getThemifyVariable('button-border-color'); border-radius: 2px; padding: #{10 / $base-font-size}rem #{30 / $base-font-size}rem; &:enabled:hover { @@ -72,6 +79,27 @@ } } +%forms-button { + background-color: $form-button-background-color; + color: $form-button-color; + cursor: pointer; + border: 2px solid $form-button-color; + border-radius: 2px; + padding: #{8 / $base-font-size}rem #{25 / $base-font-size}rem; + line-height: 1; + margin: #{39 / $base-font-size}rem 0 #{24 / $base-font-size}rem 0; + &:enabled:hover { + border-color: $form-button-background-hover-color; + background-color: $form-button-background-hover-color; + color: $form-button-hover-color; + } + &:enabled:active { + border-color: $form-button-background-active-color; + background-color: $form-button-background-active-color; + color: $form-button-active-color; + } +} + %preferences-button { @extend %toolbar-button; @include themify() { diff --git a/client/styles/abstracts/_variables.scss b/client/styles/abstracts/_variables.scss index f5eb7d78..60b4560f 100644 --- a/client/styles/abstracts/_variables.scss +++ b/client/styles/abstracts/_variables.scss @@ -37,7 +37,7 @@ $themes: ( editor-gutter-color: #f4f4f4, file-selected-color: #f4f4f4, input-text-color: #333, - input-border-color: #979797, + input-border-color: #b5b5b5, ), dark: ( logo-color: $p5js-pink, @@ -69,7 +69,7 @@ $themes: ( editor-gutter-color: #363636, file-selected-color: #404040, input-text-color: #333, - input-border-color: #979797, + input-border-color: #b5b5b5, ), contrast: ( logo-color: $yellow, @@ -101,7 +101,7 @@ $themes: ( editor-gutter-color: #454545, file-selected-color: #404040, input-text-color: #333, - input-border-color: #979797, + input-border-color: #b5b5b5, ) ); @@ -110,3 +110,13 @@ $console-error-color: #ff5f52; $toast-background-color: #979797; $toast-text-color: $white; + +$form-title-color: rgba(51, 51, 51, 0.87); +$secondary-form-title-color: #b5b5b5; +$form-button-background-color: $white; +$form-button-color: #f10046; +$form-button-background-hover-color: $p5js-pink; +$form-button-background-active-color: #f10046; +$form-button-hover-color: $white; +$form-button-active-color: $white; +$form-navigation-options-color: #999999; diff --git a/client/styles/base/_base.scss b/client/styles/base/_base.scss index 86a9592a..97edaca5 100644 --- a/client/styles/base/_base.scss +++ b/client/styles/base/_base.scss @@ -36,7 +36,8 @@ input, button { input { padding: #{5 / $base-font-size}rem; - border: 1px solid; + border: 1px solid ; + border-radius: 2px; padding: #{10 / $base-font-size}rem; @include themify() { color: getThemifyVariable('input-text-color'); @@ -46,7 +47,7 @@ input { input[type="submit"] { @include themify() { - @extend %button; + @extend %forms-button; } } diff --git a/client/styles/components/_form-container.scss b/client/styles/components/_form-container.scss new file mode 100644 index 00000000..6c4c8a61 --- /dev/null +++ b/client/styles/components/_form-container.scss @@ -0,0 +1,40 @@ +.form-container { + text-align: center; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; +} + +.form-container__header { + width: 100%; + padding: #{15 / $base-font-size}rem #{34 / $base-font-size}rem; + display: flex; + justify-content: space-between; +} + +.form-container__content { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; +} + +.form-container__title { + font-weight: normal; + color: $form-title-color; +} + +.form-container__divider { + padding: #{20 / $base-font-size}rem 0; +} + +.form-container__logo-button { + @extend %none-themify-icon; +} + +.form-container__exit-button { + @include themify() { + @extend %icon; + } +} diff --git a/client/styles/components/_forms.scss b/client/styles/components/_forms.scss index 9c6a5af5..2d6aa73e 100644 --- a/client/styles/components/_forms.scss +++ b/client/styles/components/_forms.scss @@ -1,9 +1,10 @@ .form-error { display: block; - padding-top: #{10 / $base-font-size}rem; - color: $console-error-color; + padding-top: #{4 / $base-font-size}rem; + color: $p5js-pink; width: #{300 / $base-font-size}rem; - font-size: #{12 / $base-font-size}rem; + font-size: #{9 / $base-font-size}rem; + text-align: left; } .form__cancel-button { @@ -12,6 +13,20 @@ } .form__navigation-options { - margin-top: #{10 / $base-font-size}rem; + margin-top: #{16 / $base-font-size}rem; font-size: #{12 / $base-font-size}rem; -} \ No newline at end of file + color: $form-navigation-options-color; +} + +.form__label { + color: $secondary-form-title-color; + font-size: #{12 / $base-font-size}rem; + margin-top: #{25 / $base-font-size}rem; + margin-bottom: #{7 / $base-font-size}rem; + display:block; +} + +.form__input { + width: #{360 / $base-font-size}rem; + height: #{40 / $base-font-size}rem; +} diff --git a/client/styles/components/_login.scss b/client/styles/components/_login.scss deleted file mode 100644 index 62249a6b..00000000 --- a/client/styles/components/_login.scss +++ /dev/null @@ -1,22 +0,0 @@ -.login { - @extend %modal; - text-align: center; - display: flex; - flex-direction: column; - justify-content: center; - padding: #{20 / $base-font-size}rem; - align-items: center; -} - -.login-form__email-input, -.login-form__password-input { - width: #{300 / $base-font-size}rem; -} - -.login-form__field { - margin: #{20 / $base-font-size}rem 0; -} - -.login__divider { - padding: #{20 / $base-font-size}rem 0; -} diff --git a/client/styles/components/_signup.scss b/client/styles/components/_signup.scss deleted file mode 100644 index 06f4d98c..00000000 --- a/client/styles/components/_signup.scss +++ /dev/null @@ -1,24 +0,0 @@ -.signup { - @extend %modal; - text-align: center; - display: flex; - flex-direction: column; - justify-content: center; - padding: #{20 / $base-font-size}rem; - align-items: center; -} - -.signup-form__username-input, -.signup-form__email-input, -.signup-form__password-input, -.signup-form__confirm-password-input { - width: #{300 / $base-font-size}rem; -} - -.signup-form__field { - margin: #{20 / $base-font-size}rem 0; -} - -.signup__divider { - padding: #{20 / $base-font-size}rem 0; -} diff --git a/client/styles/main.scss b/client/styles/main.scss index 13e468f4..9d5435df 100644 --- a/client/styles/main.scss +++ b/client/styles/main.scss @@ -17,8 +17,6 @@ @import 'components/nav'; @import 'components/toolbar'; @import 'components/preferences'; -@import 'components/signup'; -@import 'components/login'; @import 'components/reset-password'; @import 'components/new-password'; @import 'components/sketch-list'; @@ -33,6 +31,7 @@ @import 'components/toast'; @import 'components/timer'; @import 'components/force-authentication'; +@import 'components/form-container'; @import 'layout/ide'; @import 'layout/fullscreen';