From 0f17633f796c126e739f05539ee78d1a53a5b763 Mon Sep 17 00:00:00 2001 From: Yining Shi Date: Mon, 19 Dec 2016 16:49:37 -0500 Subject: [PATCH] New design for ResetPassword view and NewPassword view (#232) * newdesign for resetpassword view and newpassword view * bought password token back * added params.reset_password_token * no themify --- .../IDE/components/NewPasswordView.jsx | 74 -------------- .../IDE/components/ResetPasswordView.jsx | 71 -------------- client/modules/IDE/pages/IDEView.jsx | 22 ----- client/modules/User/components/LoginForm.jsx | 2 +- .../components/NewPasswordForm.jsx | 20 ++-- .../components/ResetPasswordForm.jsx | 11 ++- client/modules/User/components/SignupForm.jsx | 2 +- client/modules/User/pages/NewPasswordView.jsx | 96 +++++++++++++++++++ .../modules/User/pages/ResetPasswordView.jsx | 89 +++++++++++++++++ client/routes.jsx | 6 +- client/styles/abstracts/_placeholders.scss | 18 ++++ client/styles/abstracts/_variables.scss | 3 + client/styles/base/_base.scss | 2 +- client/styles/components/_form-container.scss | 4 +- client/styles/components/_forms.scss | 8 +- client/styles/components/_new-password.scss | 22 +---- client/styles/components/_reset-password.scss | 24 +---- 17 files changed, 246 insertions(+), 228 deletions(-) delete mode 100644 client/modules/IDE/components/NewPasswordView.jsx delete mode 100644 client/modules/IDE/components/ResetPasswordView.jsx rename client/modules/{IDE => User}/components/NewPasswordForm.jsx (69%) rename client/modules/{IDE => User}/components/ResetPasswordForm.jsx (68%) create mode 100644 client/modules/User/pages/NewPasswordView.jsx create mode 100644 client/modules/User/pages/ResetPasswordView.jsx diff --git a/client/modules/IDE/components/NewPasswordView.jsx b/client/modules/IDE/components/NewPasswordView.jsx deleted file mode 100644 index 7089cefc..00000000 --- a/client/modules/IDE/components/NewPasswordView.jsx +++ /dev/null @@ -1,74 +0,0 @@ -import React, { PropTypes } from 'react'; -import { reduxForm } from 'redux-form'; -import NewPasswordForm from './NewPasswordForm'; -import * as UserActions from '../../User/actions'; -import { bindActionCreators } from 'redux'; -import classNames from 'classnames'; -import { Link } from 'react-router'; - -class NewPasswordView extends React.Component { - componentDidMount() { - this.refs.newPassword.focus(); - // need to check if this is a valid token - this.props.validateResetPasswordToken(this.props.token); - } - - render() { - const newPasswordClass = classNames({ - 'new-password': true, - 'new-password--invalid': this.props.user.resetPasswordInvalid - }); - return ( -
-

Set a New Password

- -

- The password reset token is invalid or has expired. -

- Close -
- ); - } -} - -NewPasswordView.propTypes = { - token: PropTypes.string.isRequired, - validateResetPasswordToken: PropTypes.func.isRequired, - user: PropTypes.shape({ - resetPasswordInvalid: PropTypes.bool - }) -}; - -function validate(formProps) { - const errors = {}; - - if (!formProps.password) { - errors.password = 'Please enter a password'; - } - if (!formProps.confirmPassword) { - errors.confirmPassword = 'Please enter a password confirmation'; - } - - if (formProps.password !== formProps.confirmPassword) { - errors.password = 'Passwords must match'; - } - - return errors; -} - -function mapStateToProps(state, ownProps) { - return { - user: state.user, - token: ownProps.token - }; -} - -function mapDispatchToProps(dispatch) { - return bindActionCreators(UserActions, dispatch); -} - -export default reduxForm({ - form: 'new-password', - fields: ['password', 'confirmPassword'], - validate -}, mapStateToProps, mapDispatchToProps)(NewPasswordView); diff --git a/client/modules/IDE/components/ResetPasswordView.jsx b/client/modules/IDE/components/ResetPasswordView.jsx deleted file mode 100644 index 628531f0..00000000 --- a/client/modules/IDE/components/ResetPasswordView.jsx +++ /dev/null @@ -1,71 +0,0 @@ -import React, { PropTypes } from 'react'; -import { Link } from 'react-router'; -import * as UserActions from '../../User/actions'; -import { bindActionCreators } from 'redux'; -import { reduxForm } from 'redux-form'; -import ResetPasswordForm from './ResetPasswordForm'; -import classNames from 'classnames'; - -class ResetPasswordView extends React.Component { - componentWillMount() { - this.props.resetPasswordReset(); - } - - componentDidMount() { - this.refs.resetPassword.focus(); - } - - render() { - const resetPasswordClass = classNames({ - 'reset-password': true, - 'reset-password--submitted': this.props.user.resetPasswordInitiate - }); - return ( -
-

Reset Your Password

- -

- Your password reset email should arrive shortly. If you don't see it, check - in your spam folder as sometimes it can end up there. -

-

- Login -  or  - Sign up -

- Cancel -
- ); - } -} - -ResetPasswordView.propTypes = { - resetPasswordReset: PropTypes.func.isRequired, - user: PropTypes.shape({ - resetPasswordInitiate: PropTypes.bool - }).isRequired, -}; - -function mapStateToProps(state) { - return { - user: state.user - }; -} - -function mapDispatchToProps(dispatch) { - return bindActionCreators(UserActions, dispatch); -} - -function validate(formProps) { - const errors = {}; - if (!formProps.email) { - errors.email = 'Please enter an email'; - } - return errors; -} - -export default reduxForm({ - form: 'reset-password', - fields: ['email'], - validate -}, mapStateToProps, mapDispatchToProps)(ResetPasswordView); diff --git a/client/modules/IDE/pages/IDEView.jsx b/client/modules/IDE/pages/IDEView.jsx index 3ad02193..8f9180ca 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 ResetPasswordView from '../components/ResetPasswordView'; -import NewPasswordView from '../components/NewPasswordView'; class IDEView extends React.Component { constructor(props) { @@ -432,26 +430,6 @@ class IDEView extends React.Component { ); } })()} - {(() => { // eslint-disable-line - if (this.props.location.pathname === '/reset-password') { - return ( - - - - ); - } - })()} - {(() => { // eslint-disable-line - if (this.props.location.pathname.match(/\/reset-password\/[a-fA-F0-9]+/)) { - return ( - - - - ); - } - })()} {(() => { // eslint-disable-line if (this.props.ide.forceAuthenticationVisible) { return ( diff --git a/client/modules/User/components/LoginForm.jsx b/client/modules/User/components/LoginForm.jsx index b5a7aa67..037f2f81 100644 --- a/client/modules/User/components/LoginForm.jsx +++ b/client/modules/User/components/LoginForm.jsx @@ -4,7 +4,7 @@ import { domOnlyProps } from '../../../utils/reduxFormUtils'; function LoginForm(props) { const { fields: { email, password }, handleSubmit, submitting, pristine } = props; return ( -
+

-

+ +

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

-

+

+ {confirmPassword.touched && confirmPassword.error && {confirmPassword.error}} @@ -40,7 +42,9 @@ NewPasswordForm.propTypes = { submitting: PropTypes.bool, invalid: PropTypes.bool, pristine: PropTypes.bool, - token: PropTypes.string.isRequired + params: PropTypes.shape({ + reset_password_token: PropTypes.string, + }), }; export default NewPasswordForm; diff --git a/client/modules/IDE/components/ResetPasswordForm.jsx b/client/modules/User/components/ResetPasswordForm.jsx similarity index 68% rename from client/modules/IDE/components/ResetPasswordForm.jsx rename to client/modules/User/components/ResetPasswordForm.jsx index 0c635c94..cbc3c14f 100644 --- a/client/modules/IDE/components/ResetPasswordForm.jsx +++ b/client/modules/User/components/ResetPasswordForm.jsx @@ -4,17 +4,18 @@ import { domOnlyProps } from '../../../utils/reduxFormUtils'; function ResetPasswordForm(props) { const { fields: { email }, handleSubmit, submitting, invalid, pristine } = props; return ( - -

+ +

+

- +
); } diff --git a/client/modules/User/components/SignupForm.jsx b/client/modules/User/components/SignupForm.jsx index 07e6060b..ffc33cf6 100644 --- a/client/modules/User/components/SignupForm.jsx +++ b/client/modules/User/components/SignupForm.jsx @@ -4,7 +4,7 @@ import { domOnlyProps } from '../../../utils/reduxFormUtils'; function SignupForm(props) { const { fields: { username, email, password, confirmPassword }, handleSubmit, submitting, invalid, pristine } = props; return ( -
+

+

+ + +
+
+

Set a New Password

+ +

+ The password reset token is invalid or has expired. +

+
+ + ); + } +} + +NewPasswordView.propTypes = { + params: PropTypes.shape({ + reset_password_token: PropTypes.string, + }), + validateResetPasswordToken: PropTypes.func.isRequired, + user: PropTypes.shape({ + resetPasswordInvalid: PropTypes.bool + }) +}; + +function validate(formProps) { + const errors = {}; + + if (!formProps.password) { + errors.password = 'Please enter a password'; + } + if (!formProps.confirmPassword) { + errors.confirmPassword = 'Please enter a password confirmation'; + } + + if (formProps.password !== formProps.confirmPassword) { + errors.password = 'Passwords must match'; + } + + return errors; +} + +function mapStateToProps(state) { + return { + user: state.user + }; +} + +function mapDispatchToProps(dispatch) { + return bindActionCreators(UserActions, dispatch); +} + +export default reduxForm({ + form: 'new-password', + fields: ['password', 'confirmPassword'], + validate +}, mapStateToProps, mapDispatchToProps)(NewPasswordView); diff --git a/client/modules/User/pages/ResetPasswordView.jsx b/client/modules/User/pages/ResetPasswordView.jsx new file mode 100644 index 00000000..230bdc4e --- /dev/null +++ b/client/modules/User/pages/ResetPasswordView.jsx @@ -0,0 +1,89 @@ +import React, { PropTypes } from 'react'; +import { Link, browserHistory } from 'react-router'; +import * as UserActions from '../actions'; +import { bindActionCreators } from 'redux'; +import { reduxForm } from 'redux-form'; +import ResetPasswordForm from '../components/ResetPasswordForm'; +import classNames from 'classnames'; +import InlineSVG from 'react-inlinesvg'; +const exitUrl = require('../../../images/exit.svg'); +const logoUrl = require('../../../images/p5js-logo.svg'); + +class ResetPasswordView extends React.Component { + constructor(props) { + super(props); + this.gotoHomePage = this.gotoHomePage.bind(this); + } + + componentWillMount() { + this.props.resetPasswordReset(); + } + + gotoHomePage() { + browserHistory.push('/'); + } + + render() { + const resetPasswordClass = classNames({ + 'reset-password': true, + 'reset-password--submitted': this.props.user.resetPasswordInitiate, + 'form-container': true + }); + return ( +
+
+ + +
+
+

Reset Your Password

+ +

+ Your password reset email should arrive shortly. If you don't see it, check + in your spam folder as sometimes it can end up there. +

+

+ Log In +  or  + Sign Up +

+
+
+ ); + } +} + +ResetPasswordView.propTypes = { + resetPasswordReset: PropTypes.func.isRequired, + user: PropTypes.shape({ + resetPasswordInitiate: PropTypes.bool + }).isRequired, +}; + +function mapStateToProps(state) { + return { + user: state.user + }; +} + +function mapDispatchToProps(dispatch) { + return bindActionCreators(UserActions, dispatch); +} + +function validate(formProps) { + const errors = {}; + if (!formProps.email) { + errors.email = 'Please enter an email'; + } + return errors; +} + +export default reduxForm({ + form: 'reset-password', + fields: ['email'], + validate +}, mapStateToProps, mapDispatchToProps)(ResetPasswordView); diff --git a/client/routes.jsx b/client/routes.jsx index 34e9b950..45b2b326 100644 --- a/client/routes.jsx +++ b/client/routes.jsx @@ -5,6 +5,8 @@ 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 ResetPasswordView from './modules/User/pages/ResetPasswordView'; +import NewPasswordView from './modules/User/pages/NewPasswordView'; // import SketchListView from './modules/Sketch/pages/SketchListView'; import { getUser } from './modules/User/actions'; @@ -18,8 +20,8 @@ const routes = (store) => - - + + diff --git a/client/styles/abstracts/_placeholders.scss b/client/styles/abstracts/_placeholders.scss index 23fa9b15..6102d489 100644 --- a/client/styles/abstracts/_placeholders.scss +++ b/client/styles/abstracts/_placeholders.scss @@ -58,6 +58,24 @@ padding: 0; } +%none-themify-icon-with-hover { + color: $icon-color; + & g { + fill: $icon-color; + } + &:hover { + color: $icon-hover-color; + & g { + opacity: 1; + fill: $icon-hover-color; + } + } + background-color: transparent; + border: none; + cursor: pointer; + padding: 0; +} + %button { @include themify() { background-color: getThemifyVariable('button-background-color'); diff --git a/client/styles/abstracts/_variables.scss b/client/styles/abstracts/_variables.scss index 60b4560f..ea95e2ad 100644 --- a/client/styles/abstracts/_variables.scss +++ b/client/styles/abstracts/_variables.scss @@ -120,3 +120,6 @@ $form-button-background-active-color: #f10046; $form-button-hover-color: $white; $form-button-active-color: $white; $form-navigation-options-color: #999999; + +$icon-color: #8b8b8b; +$icon-hover-color: #333; diff --git a/client/styles/base/_base.scss b/client/styles/base/_base.scss index 97edaca5..57cb71a1 100644 --- a/client/styles/base/_base.scss +++ b/client/styles/base/_base.scss @@ -47,7 +47,7 @@ input { input[type="submit"] { @include themify() { - @extend %forms-button; + @extend %button; } } diff --git a/client/styles/components/_form-container.scss b/client/styles/components/_form-container.scss index 6c4c8a61..5f4a96a4 100644 --- a/client/styles/components/_form-container.scss +++ b/client/styles/components/_form-container.scss @@ -34,7 +34,5 @@ } .form-container__exit-button { - @include themify() { - @extend %icon; - } + @extend %none-themify-icon-with-hover; } diff --git a/client/styles/components/_forms.scss b/client/styles/components/_forms.scss index 2d6aa73e..88193b26 100644 --- a/client/styles/components/_forms.scss +++ b/client/styles/components/_forms.scss @@ -23,10 +23,16 @@ font-size: #{12 / $base-font-size}rem; margin-top: #{25 / $base-font-size}rem; margin-bottom: #{7 / $base-font-size}rem; - display:block; + display: block; } .form__input { width: #{360 / $base-font-size}rem; height: #{40 / $base-font-size}rem; + color: $icon-hover-color; + border-color: $secondary-form-title-color; +} + +.form input[type="submit"] { + @extend %forms-button; } diff --git a/client/styles/components/_new-password.scss b/client/styles/components/_new-password.scss index a559c5c1..8f81d48b 100644 --- a/client/styles/components/_new-password.scss +++ b/client/styles/components/_new-password.scss @@ -1,22 +1,3 @@ -.new-password { - @extend %modal; - text-align: center; - display: flex; - flex-direction: column; - justify-content: center; - padding: #{20 / $base-font-size}rem; - align-items: center; -} - -.new-password-form__password-input, -.new-password-form__confirm-password-input { - width: #{300 / $base-font-size}rem; -} - -.new-password-form__field { - margin: #{20 / $base-font-size}rem 0; -} - .new-password-form { .new-password--invalid & { display: none; @@ -27,5 +8,8 @@ display: none; .new-password--invalid & { display: block; + margin-top: #{40 / $base-font-size}rem; + margin-bottom: #{80 / $base-font-size}rem; + color: $form-navigation-options-color; } } \ No newline at end of file diff --git a/client/styles/components/_reset-password.scss b/client/styles/components/_reset-password.scss index 83b7dfda..f0bb7608 100644 --- a/client/styles/components/_reset-password.scss +++ b/client/styles/components/_reset-password.scss @@ -1,29 +1,13 @@ -.reset-password { - @extend %modal; - text-align: center; - display: flex; - flex-direction: column; - justify-content: center; - padding: #{20 / $base-font-size}rem; - align-items: center; -} - -.reset-password-form__email-input { - width: #{300 / $base-font-size}rem; -} - -.reset-password-form__field { - margin: #{20 / $base-font-size}rem 0; -} - .reset-password__submitted { - width: #{300 / $base-font-size}rem; + width: #{360 / $base-font-size}rem; display: none; text-align: left; font-size: #{12 / $base-font-size}rem; margin-top: #{10 / $base-font-size}rem; + color: $form-navigation-options-color; + padding-right: #{30 / $base-font-size}rem; + padding-left: #{39 / $base-font-size}rem; .reset-password--submitted & { display: block; - } }