Merge branch 'feature/mobile-examples' of https://github.com/ghalestrilo/p5.js-web-editor into feature/mobile-login
This commit is contained in:
commit
87784e5a83
6 changed files with 93 additions and 58 deletions
|
@ -608,13 +608,13 @@ class Nav extends React.PureComponent {
|
||||||
<ul className="nav__items-right" title="user-menu">
|
<ul className="nav__items-right" title="user-menu">
|
||||||
<li className="nav__item">
|
<li className="nav__item">
|
||||||
<Link to="/login" className="nav__auth-button">
|
<Link to="/login" className="nav__auth-button">
|
||||||
<span className="nav__item-header">{this.props.t('Nav.Login.Login')}</span>
|
<span className="nav__item-header">{this.props.t('Nav.Login')}</span>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<span className="nav__item-or">{this.props.t('Nav.Login.LoginOr')}</span>
|
<span className="nav__item-or">{this.props.t('Nav.LoginOr')}</span>
|
||||||
<li className="nav__item">
|
<li className="nav__item">
|
||||||
<Link to="/signup" className="nav__auth-button">
|
<Link to="/signup" className="nav__auth-button">
|
||||||
<span className="nav__item-header">{this.props.t('Nav.Login.SignUp')}</span>
|
<span className="nav__item-header">{this.props.t('Nav.SignUp')}</span>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
|
import i18n from 'i18next';
|
||||||
import Button from '../../../common/Button';
|
import Button from '../../../common/Button';
|
||||||
|
|
||||||
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
||||||
|
@ -18,12 +19,10 @@ function LoginForm(props) {
|
||||||
onSubmit={handleSubmit(props.validateAndLoginUser.bind(this, props.previousPath))}
|
onSubmit={handleSubmit(props.validateAndLoginUser.bind(this, props.previousPath))}
|
||||||
>
|
>
|
||||||
<p className="form__field">
|
<p className="form__field">
|
||||||
<label htmlFor="email" className="form__label">
|
<label htmlFor="email" className="form__label">{props.t('LoginForm.UsernameOrEmail')}</label>
|
||||||
Email or Username
|
|
||||||
</label>
|
|
||||||
<input
|
<input
|
||||||
className="form__input"
|
className="form__input"
|
||||||
aria-label="email or username"
|
aria-label={props.t('LoginForm.UsernameOrEmailARIA')}
|
||||||
type="text"
|
type="text"
|
||||||
id="email"
|
id="email"
|
||||||
{...domOnlyProps(email)}
|
{...domOnlyProps(email)}
|
||||||
|
@ -33,12 +32,10 @@ function LoginForm(props) {
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<p className="form__field">
|
<p className="form__field">
|
||||||
<label htmlFor="password" className="form__label">
|
<label htmlFor="password" className="form__label">{props.t('LoginForm.Password')}</label>
|
||||||
Password
|
|
||||||
</label>
|
|
||||||
<input
|
<input
|
||||||
className="form__input"
|
className="form__input"
|
||||||
aria-label="password"
|
aria-label={props.t('LoginForm.PasswordARIA')}
|
||||||
type="password"
|
type="password"
|
||||||
id="password"
|
id="password"
|
||||||
{...domOnlyProps(password)}
|
{...domOnlyProps(password)}
|
||||||
|
@ -47,8 +44,10 @@ function LoginForm(props) {
|
||||||
<span className="form-error">{password.error}</span>
|
<span className="form-error">{password.error}</span>
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<Button type="submit" disabled={submitting || pristine}>
|
<Button
|
||||||
Log In
|
type="submit"
|
||||||
|
disabled={submitting || pristine}
|
||||||
|
>{props.t('LoginForm.Submit')}
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
@ -65,6 +64,7 @@ LoginForm.propTypes = {
|
||||||
pristine: PropTypes.bool,
|
pristine: PropTypes.bool,
|
||||||
invalid: PropTypes.bool,
|
invalid: PropTypes.bool,
|
||||||
previousPath: PropTypes.string.isRequired,
|
previousPath: PropTypes.string.isRequired,
|
||||||
|
t: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
LoginForm.defaultProps = {
|
LoginForm.defaultProps = {
|
||||||
|
@ -73,4 +73,4 @@ LoginForm.defaultProps = {
|
||||||
invalid: false,
|
invalid: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default LoginForm;
|
export default withTranslation()(LoginForm);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
import i18n from 'i18next';
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { remSize } from '../../../theme';
|
import { remSize } from '../../../theme';
|
||||||
|
|
||||||
|
@ -12,11 +14,6 @@ const authUrls = {
|
||||||
google: '/auth/google'
|
google: '/auth/google'
|
||||||
};
|
};
|
||||||
|
|
||||||
const labels = {
|
|
||||||
github: 'Login with GitHub',
|
|
||||||
google: 'Login with Google'
|
|
||||||
};
|
|
||||||
|
|
||||||
const icons = {
|
const icons = {
|
||||||
github: GithubIcon,
|
github: GithubIcon,
|
||||||
google: GoogleIcon
|
google: GoogleIcon
|
||||||
|
@ -31,11 +28,15 @@ const StyledButton = styled(Button)`
|
||||||
width: ${remSize(300)};
|
width: ${remSize(300)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function SocialAuthButton({ service }) {
|
function SocialAuthButton({ service, t }) {
|
||||||
const ServiceIcon = icons[service];
|
const ServiceIcon = icons[service];
|
||||||
|
const labels = {
|
||||||
|
github: t('SocialAuthButton.Github'),
|
||||||
|
google: t('SocialAuthButton.Google')
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
iconBefore={<ServiceIcon aria-label={`${service} logo`} />}
|
iconBefore={<ServiceIcon aria-label={t('SocialAuthButton.LogoARIA', { serviceauth: service })} />}
|
||||||
href={authUrls[service]}
|
href={authUrls[service]}
|
||||||
>
|
>
|
||||||
{labels[service]}
|
{labels[service]}
|
||||||
|
@ -46,7 +47,10 @@ function SocialAuthButton({ service }) {
|
||||||
SocialAuthButton.services = services;
|
SocialAuthButton.services = services;
|
||||||
|
|
||||||
SocialAuthButton.propTypes = {
|
SocialAuthButton.propTypes = {
|
||||||
service: PropTypes.oneOf(['github', 'google']).isRequired
|
service: PropTypes.oneOf(['github', 'google']).isRequired,
|
||||||
|
t: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SocialAuthButton;
|
const SocialAuthButtonPublic = withTranslation()(SocialAuthButton);
|
||||||
|
SocialAuthButtonPublic.services = services;
|
||||||
|
export default SocialAuthButtonPublic;
|
||||||
|
|
|
@ -3,6 +3,8 @@ import React from 'react';
|
||||||
import { reduxForm } from 'redux-form';
|
import { reduxForm } from 'redux-form';
|
||||||
import { Link, browserHistory } from 'react-router';
|
import { Link, browserHistory } from 'react-router';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
|
import { withTranslation } from 'react-i18next';
|
||||||
|
import i18n from 'i18next';
|
||||||
import { validateAndLoginUser } from '../actions';
|
import { validateAndLoginUser } from '../actions';
|
||||||
import LoginForm from '../components/LoginForm';
|
import LoginForm from '../components/LoginForm';
|
||||||
import { validateLogin } from '../../../utils/reduxFormUtils';
|
import { validateLogin } from '../../../utils/reduxFormUtils';
|
||||||
|
@ -34,23 +36,23 @@ class LoginView extends React.Component {
|
||||||
<Nav layout="dashboard" />
|
<Nav layout="dashboard" />
|
||||||
<main className="form-container">
|
<main className="form-container">
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>p5.js Web Editor | Login</title>
|
<title>{this.props.t('LoginView.Title')}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<div className="form-container__content">
|
<div className="form-container__content">
|
||||||
<h2 className="form-container__title">Log In</h2>
|
<h2 className="form-container__title">{this.props.t('LoginView.Login')}</h2>
|
||||||
<LoginForm {...this.props} />
|
<LoginForm {...this.props} />
|
||||||
<h2 className="form-container__divider">Or</h2>
|
<h2 className="form-container__divider">{this.props.t('LoginView.LoginOr')}</h2>
|
||||||
<div className="form-container__stack">
|
<div className="form-container__stack">
|
||||||
<SocialAuthButton service={SocialAuthButton.services.github} />
|
<SocialAuthButton service={SocialAuthButton.services.github} />
|
||||||
<SocialAuthButton service={SocialAuthButton.services.google} />
|
<SocialAuthButton service={SocialAuthButton.services.google} />
|
||||||
</div>
|
</div>
|
||||||
<p className="form__navigation-options">
|
<p className="form__navigation-options">
|
||||||
Don't have an account?
|
{this.props.t('LoginView.DontHaveAccount')}
|
||||||
<Link className="form__signup-button" to="/signup">Sign Up</Link>
|
<Link className="form__signup-button" to="/signup">{this.props.t('LoginView.SignUp')}</Link>
|
||||||
</p>
|
</p>
|
||||||
<p className="form__navigation-options">
|
<p className="form__navigation-options">
|
||||||
Forgot your password?
|
{this.props.t('LoginView.ForgotPassword')}
|
||||||
<Link className="form__reset-password-button" to="/reset-password">Reset your password</Link>
|
<Link className="form__reset-password-button" to="/reset-password"> {this.props.t('LoginView.ResetPassword')}</Link>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -76,7 +78,8 @@ LoginView.propTypes = {
|
||||||
previousPath: PropTypes.string.isRequired,
|
previousPath: PropTypes.string.isRequired,
|
||||||
user: PropTypes.shape({
|
user: PropTypes.shape({
|
||||||
authenticated: PropTypes.bool
|
authenticated: PropTypes.bool
|
||||||
})
|
}),
|
||||||
|
t: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
LoginView.defaultProps = {
|
LoginView.defaultProps = {
|
||||||
|
@ -85,8 +88,8 @@ LoginView.defaultProps = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default reduxForm({
|
export default withTranslation()(reduxForm({
|
||||||
form: 'login',
|
form: 'login',
|
||||||
fields: ['email', 'password'],
|
fields: ['email', 'password'],
|
||||||
validate: validateLogin
|
validate: validateLogin
|
||||||
}, mapStateToProps, mapDispatchToProps)(LoginView);
|
}, mapStateToProps, mapDispatchToProps)(LoginView));
|
||||||
|
|
|
@ -33,18 +33,9 @@
|
||||||
"Lang": "Language",
|
"Lang": "Language",
|
||||||
"BackEditor": "Back to Editor",
|
"BackEditor": "Back to Editor",
|
||||||
"WarningUnsavedChanges": "Are you sure you want to leave this page? You have unsaved changes.",
|
"WarningUnsavedChanges": "Are you sure you want to leave this page? You have unsaved changes.",
|
||||||
"Login": {
|
|
||||||
"Login": "Log in",
|
"Login": "Log in",
|
||||||
"LoginOr": "or",
|
"LoginOr": "or",
|
||||||
"SignUp": "Sign up",
|
"SignUp": "Sign up",
|
||||||
"Email": "email",
|
|
||||||
"Username": "username",
|
|
||||||
"LoginGithub": "Login with Github",
|
|
||||||
"LoginGoogle": "Login with Google",
|
|
||||||
"DontHaveAccount": "Don't have an account?",
|
|
||||||
"ForgotPassword": "Forgot your password?",
|
|
||||||
"ResetPassword": "Reset your password"
|
|
||||||
},
|
|
||||||
"Auth": {
|
"Auth": {
|
||||||
"Welcome": "Welcome",
|
"Welcome": "Welcome",
|
||||||
"Hello": "Hello",
|
"Hello": "Hello",
|
||||||
|
@ -57,6 +48,29 @@
|
||||||
"LogOut": "Log Out"
|
"LogOut": "Log Out"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"LoginForm": {
|
||||||
|
"UsernameOrEmail": "Email or Username",
|
||||||
|
"UsernameOrEmailARIA": "Email or Username",
|
||||||
|
"Password": "Password",
|
||||||
|
"PasswordARIA": "Password",
|
||||||
|
"Submit": "Log In"
|
||||||
|
},
|
||||||
|
"LoginView": {
|
||||||
|
"Title": "p5.js Web Editor | Login",
|
||||||
|
"Login": "Log In",
|
||||||
|
"LoginOr": "or",
|
||||||
|
"SignUp": "Sign Up",
|
||||||
|
"Email": "email",
|
||||||
|
"Username": "username",
|
||||||
|
"DontHaveAccount": "Don't have an account? ",
|
||||||
|
"ForgotPassword": "Forgot your password? ",
|
||||||
|
"ResetPassword": "Reset your password"
|
||||||
|
},
|
||||||
|
"SocialAuthButton": {
|
||||||
|
"Github": "Login with Github",
|
||||||
|
"LogoARIA": "{{serviceauth}} logo",
|
||||||
|
"Google": "Login with Google"
|
||||||
|
},
|
||||||
"About": {
|
"About": {
|
||||||
"Title": "About",
|
"Title": "About",
|
||||||
"TitleHelmet": "p5.js Web Editor | About",
|
"TitleHelmet": "p5.js Web Editor | About",
|
||||||
|
|
|
@ -33,18 +33,9 @@
|
||||||
"Lang": "Lenguaje",
|
"Lang": "Lenguaje",
|
||||||
"BackEditor": "Regresa al editor",
|
"BackEditor": "Regresa al editor",
|
||||||
"WarningUnsavedChanges": "¿Realmente quieres salir de la página? Tienes cambios sin guardar.",
|
"WarningUnsavedChanges": "¿Realmente quieres salir de la página? Tienes cambios sin guardar.",
|
||||||
"Login": {
|
|
||||||
"Login": "Ingresa",
|
"Login": "Ingresa",
|
||||||
"LoginOr": "o",
|
"LoginOr": "o",
|
||||||
"SignUp": "registráte",
|
"SignUp": "Registráte",
|
||||||
"Email": "correo electrónico",
|
|
||||||
"Username": "Identificación",
|
|
||||||
"LoginGithub": "Ingresa con Github",
|
|
||||||
"LoginGoogle": "Ingresa con Google",
|
|
||||||
"DontHaveAccount": "¿No tienes cuenta?",
|
|
||||||
"ForgotPassword": "¿Olvidaste tu contraseña?",
|
|
||||||
"ResetPassword": "Regenera tu contraseña"
|
|
||||||
},
|
|
||||||
"Auth": {
|
"Auth": {
|
||||||
"Welcome": "Hola",
|
"Welcome": "Hola",
|
||||||
"Hello": "Hola",
|
"Hello": "Hola",
|
||||||
|
@ -57,6 +48,29 @@
|
||||||
"LogOut": "Cerrar sesión"
|
"LogOut": "Cerrar sesión"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"LoginForm": {
|
||||||
|
"UsernameOrEmail": "Correo o Identificación",
|
||||||
|
"UsernameOrEmailARIA": "Introduce Correo o Identificación",
|
||||||
|
"Password": "Contraseña",
|
||||||
|
"PasswordARIA": "Contraseña",
|
||||||
|
"Submit": "Ingresa"
|
||||||
|
},
|
||||||
|
"LoginView": {
|
||||||
|
"Title": " Editor Web p5.js | Ingreso",
|
||||||
|
"Login": "Ingresa",
|
||||||
|
"LoginOr": "o",
|
||||||
|
"SignUp": "Registráte",
|
||||||
|
"Email": "correo electrónico",
|
||||||
|
"Username": "Identificación",
|
||||||
|
"DontHaveAccount": "¿No tienes cuenta? ",
|
||||||
|
"ForgotPassword": "¿Olvidaste tu contraseña? ",
|
||||||
|
"ResetPassword": "Regenera tu contraseña"
|
||||||
|
},
|
||||||
|
"SocialAuthButton": {
|
||||||
|
"Github": "Ingresa con Github",
|
||||||
|
"LogoARIA": "Logo de {{serviceauth}}",
|
||||||
|
"Google": "Ingresa con Google"
|
||||||
|
},
|
||||||
"About": {
|
"About": {
|
||||||
"Title": "Acerca de",
|
"Title": "Acerca de",
|
||||||
"TitleHelmet": "Editor Web p5.js | Acerca de",
|
"TitleHelmet": "Editor Web p5.js | Acerca de",
|
||||||
|
|
Loading…
Reference in a new issue