Replace User form buttons with shared Button component
This commit is contained in:
parent
b61bd69505
commit
96ecb3e4a0
15 changed files with 129 additions and 118 deletions
|
@ -1,23 +0,0 @@
|
||||||
import InlineSVG from 'react-inlinesvg';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
const githubUrl = require('../../../images/github.svg');
|
|
||||||
|
|
||||||
function GithubButton(props) {
|
|
||||||
return (
|
|
||||||
<a
|
|
||||||
className="github-button"
|
|
||||||
href="/auth/github"
|
|
||||||
>
|
|
||||||
<InlineSVG src={githubUrl} className="github-icon" />
|
|
||||||
<span>{props.buttonText}</span>
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GithubButton.propTypes = {
|
|
||||||
buttonText: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default GithubButton;
|
|
|
@ -1,23 +0,0 @@
|
||||||
import InlineSVG from 'react-inlinesvg';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import googleUrl from '../../../images/google.svg';
|
|
||||||
|
|
||||||
function GoogleButton(props) {
|
|
||||||
return (
|
|
||||||
<a
|
|
||||||
className="google-button"
|
|
||||||
href="/auth/google/"
|
|
||||||
>
|
|
||||||
<InlineSVG src={googleUrl} className="google-icon" />
|
|
||||||
<span>{props.buttonText}</span>
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
GoogleButton.propTypes = {
|
|
||||||
buttonText: PropTypes.string.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default GoogleButton;
|
|
|
@ -1,6 +1,8 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
||||||
|
import Button from '../../../common/Button';
|
||||||
|
|
||||||
function NewPasswordForm(props) {
|
function NewPasswordForm(props) {
|
||||||
const {
|
const {
|
||||||
|
@ -34,7 +36,7 @@ function NewPasswordForm(props) {
|
||||||
<span className="form-error">{confirmPassword.error}</span>
|
<span className="form-error">{confirmPassword.error}</span>
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
<input type="submit" disabled={submitting || invalid || pristine} value="Set New Password" aria-label="sign up" />
|
<Button type="submit" disabled={submitting || invalid || pristine} label="sign up">Set New Password</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
||||||
|
import Button from '../../../common/Button';
|
||||||
|
|
||||||
function ResetPasswordForm(props) {
|
function ResetPasswordForm(props) {
|
||||||
const {
|
const {
|
||||||
|
@ -19,12 +21,12 @@ function ResetPasswordForm(props) {
|
||||||
/>
|
/>
|
||||||
{email.touched && email.error && <span className="form-error">{email.error}</span>}
|
{email.touched && email.error && <span className="form-error">{email.error}</span>}
|
||||||
</p>
|
</p>
|
||||||
<input
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={submitting || invalid || pristine || props.user.resetPasswordInitiate}
|
disabled={submitting || invalid || pristine || props.user.resetPasswordInitiate}
|
||||||
value="Send Password Reset Email"
|
label="Send email to reset password"
|
||||||
aria-label="Send email to reset password"
|
>Send Password Reset Email
|
||||||
/>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
import { domOnlyProps } from '../../../utils/reduxFormUtils';
|
||||||
|
import Button from '../../../common/Button';
|
||||||
|
|
||||||
function SignupForm(props) {
|
function SignupForm(props) {
|
||||||
const {
|
const {
|
||||||
|
@ -58,7 +60,12 @@ function SignupForm(props) {
|
||||||
<span className="form-error">{confirmPassword.error}</span>
|
<span className="form-error">{confirmPassword.error}</span>
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
<input type="submit" disabled={submitting || invalid || pristine} value="Sign Up" aria-label="sign up" />
|
<Button
|
||||||
|
type="submit"
|
||||||
|
disabled={submitting || invalid || pristine}
|
||||||
|
label="sign up"
|
||||||
|
>Sign Up
|
||||||
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
55
client/modules/User/components/SocialAuthButton.jsx
Normal file
55
client/modules/User/components/SocialAuthButton.jsx
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
import { remSize, prop } from '../../../theme';
|
||||||
|
|
||||||
|
import Button from '../../../common/Button';
|
||||||
|
import Icon from '../../../common/Icon';
|
||||||
|
|
||||||
|
const authUrls = {
|
||||||
|
github: '/auth-github',
|
||||||
|
google: '/auth/google/'
|
||||||
|
};
|
||||||
|
|
||||||
|
const labels = {
|
||||||
|
github: 'Login with GitHub',
|
||||||
|
google: 'Login with Google'
|
||||||
|
};
|
||||||
|
|
||||||
|
const services = {
|
||||||
|
github: 'github',
|
||||||
|
google: 'google'
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledButton = styled(Button)`
|
||||||
|
width: ${remSize(300)};
|
||||||
|
|
||||||
|
> * + * {
|
||||||
|
margin-left: ${remSize(10)};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledIcon = styled(Icon)`
|
||||||
|
width: ${remSize(32)};
|
||||||
|
height: ${remSize(32)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
function SocialAuthButton({ service }) {
|
||||||
|
return (
|
||||||
|
<StyledButton
|
||||||
|
href={authUrls[service]}
|
||||||
|
>
|
||||||
|
<StyledIcon name={Icon.names[service]} />
|
||||||
|
<span>{labels[service]}</span>
|
||||||
|
</StyledButton>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SocialAuthButton.services = services;
|
||||||
|
|
||||||
|
SocialAuthButton.propTypes = {
|
||||||
|
service: PropTypes.oneOf(['github', 'google']).isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SocialAuthButton;
|
16
client/modules/User/components/SocialAuthButton.stories.jsx
Normal file
16
client/modules/User/components/SocialAuthButton.stories.jsx
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import SocialAuthButton from './SocialAuthButton';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'User/components/SocialAuthButton',
|
||||||
|
component: SocialAuthButton
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Github = () => (
|
||||||
|
<SocialAuthButton service={SocialAuthButton.services.github}>Log in with Github</SocialAuthButton>
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Google = () => (
|
||||||
|
<SocialAuthButton service={SocialAuthButton.services.google}>Sign up with Google</SocialAuthButton>
|
||||||
|
);
|
|
@ -8,8 +8,7 @@ import { Helmet } from 'react-helmet';
|
||||||
import { updateSettings, initiateVerification, createApiKey, removeApiKey } from '../actions';
|
import { updateSettings, initiateVerification, createApiKey, removeApiKey } from '../actions';
|
||||||
import AccountForm from '../components/AccountForm';
|
import AccountForm from '../components/AccountForm';
|
||||||
import { validateSettings } from '../../../utils/reduxFormUtils';
|
import { validateSettings } from '../../../utils/reduxFormUtils';
|
||||||
import GithubButton from '../components/GithubButton';
|
import SocialAuthButton from '../components/SocialAuthButton';
|
||||||
import GoogleButton from '../components/GoogleButton';
|
|
||||||
import APIKeyForm from '../components/APIKeyForm';
|
import APIKeyForm from '../components/APIKeyForm';
|
||||||
import Nav from '../../../components/Nav';
|
import Nav from '../../../components/Nav';
|
||||||
|
|
||||||
|
@ -24,8 +23,8 @@ function SocialLoginPanel(props) {
|
||||||
<p className="account__social-text">
|
<p className="account__social-text">
|
||||||
Use your GitHub or Google account to log into the p5.js Web Editor.
|
Use your GitHub or Google account to log into the p5.js Web Editor.
|
||||||
</p>
|
</p>
|
||||||
<GithubButton buttonText="Login with GitHub" />
|
<SocialAuthButton service={SocialAuthButton.services.github} />
|
||||||
<GoogleButton buttonText="Login with Google" />
|
<SocialAuthButton service={SocialAuthButton.services.google} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@ import PropTypes from 'prop-types';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { browserHistory, Link } from 'react-router';
|
import { browserHistory } from 'react-router';
|
||||||
import { updateSettings, initiateVerification, createApiKey, removeApiKey } from '../actions';
|
import { updateSettings, initiateVerification, createApiKey, removeApiKey } from '../actions';
|
||||||
|
|
||||||
|
import Button from '../../../common/Button';
|
||||||
|
|
||||||
import Nav from '../../../components/Nav';
|
import Nav from '../../../components/Nav';
|
||||||
import Overlay from '../../App/components/Overlay';
|
import Overlay from '../../App/components/Overlay';
|
||||||
|
|
||||||
|
@ -79,16 +82,16 @@ class DashboardView extends React.Component {
|
||||||
case TabKey.collections:
|
case TabKey.collections:
|
||||||
return this.isOwner() && (
|
return this.isOwner() && (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Link className="dashboard__action-button" to={`/${username}/collections/create`}>
|
<Button to={`/${username}/collections/create`}>
|
||||||
Create collection
|
Create collection
|
||||||
</Link>
|
</Button>
|
||||||
<CollectionSearchbar />
|
<CollectionSearchbar />
|
||||||
</React.Fragment>);
|
</React.Fragment>);
|
||||||
case TabKey.sketches:
|
case TabKey.sketches:
|
||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{this.isOwner() && <Link className="dashboard__action-button" to="/">New sketch</Link>}
|
{this.isOwner() && <Button to="/">New sketch</Button>}
|
||||||
<SketchSearchbar />
|
<SketchSearchbar />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,8 +6,7 @@ import { Helmet } from 'react-helmet';
|
||||||
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';
|
||||||
import GithubButton from '../components/GithubButton';
|
import SocialAuthButton from '../components/SocialAuthButton';
|
||||||
import GoogleButton from '../components/GoogleButton';
|
|
||||||
import Nav from '../../../components/Nav';
|
import Nav from '../../../components/Nav';
|
||||||
|
|
||||||
class LoginView extends React.Component {
|
class LoginView extends React.Component {
|
||||||
|
@ -41,8 +40,10 @@ class LoginView extends React.Component {
|
||||||
<h2 className="form-container__title">Log In</h2>
|
<h2 className="form-container__title">Log In</h2>
|
||||||
<LoginForm {...this.props} />
|
<LoginForm {...this.props} />
|
||||||
<h2 className="form-container__divider">Or</h2>
|
<h2 className="form-container__divider">Or</h2>
|
||||||
<GithubButton buttonText="Login with Github" />
|
<div className="form-container__stack">
|
||||||
<GoogleButton buttonText="Login with Google" />
|
<SocialAuthButton service={SocialAuthButton.services.github} />
|
||||||
|
<SocialAuthButton service={SocialAuthButton.services.google} />
|
||||||
|
</div>
|
||||||
<p className="form__navigation-options">
|
<p className="form__navigation-options">
|
||||||
Don't have an account?
|
Don't have an account?
|
||||||
<Link className="form__signup-button" to="/signup">Sign Up</Link>
|
<Link className="form__signup-button" to="/signup">Sign Up</Link>
|
||||||
|
|
|
@ -83,8 +83,3 @@
|
||||||
.dashboard-header__actions > *:not(:first-child) {
|
.dashboard-header__actions > *:not(:first-child) {
|
||||||
margin-left: #{15 / $base-font-size}rem;
|
margin-left: #{15 / $base-font-size}rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard__action-button {
|
|
||||||
flex-grow: 0;
|
|
||||||
@extend %button;
|
|
||||||
}
|
|
||||||
|
|
|
@ -57,3 +57,7 @@
|
||||||
.form-container__exit-button {
|
.form-container__exit-button {
|
||||||
@include icon();
|
@include icon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-container__stack > * + * {
|
||||||
|
margin-top: #{10 / $base-font-size}rem;
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form > * + * {
|
||||||
|
margin-top: #{12 / $base-font-size}rem;
|
||||||
|
}
|
||||||
|
|
||||||
.form--inline {
|
.form--inline {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -78,20 +82,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.form [type="submit"] {
|
.form [type="submit"] {
|
||||||
@extend %button;
|
margin-left: auto;
|
||||||
padding: #{8 / $base-font-size}rem #{25 / $base-font-size}rem;
|
margin-right: auto;
|
||||||
margin: #{39 / $base-font-size}rem 0 #{24 / $base-font-size}rem 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form [type="submit"][disabled] {
|
// .form [type="submit"] {
|
||||||
cursor: not-allowed;
|
// @extend %button;
|
||||||
}
|
// padding: #{8 / $base-font-size}rem #{25 / $base-font-size}rem;
|
||||||
|
// margin: #{39 / $base-font-size}rem 0 #{24 / $base-font-size}rem 0;
|
||||||
|
// }
|
||||||
|
|
||||||
.form--inline [type="submit"] {
|
// .form [type="submit"][disabled] {
|
||||||
margin: 0 0 0 #{24 / $base-font-size}rem;
|
// cursor: not-allowed;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.form [type="submit"][disabled],
|
// .form--inline [type="submit"] {
|
||||||
.form--inline [type="submit"][disabled] {
|
// margin: 0 0 0 #{24 / $base-font-size}rem;
|
||||||
cursor: not-allowed;
|
// }
|
||||||
}
|
|
||||||
|
// .form [type="submit"][disabled],
|
||||||
|
// .form--inline [type="submit"][disabled] {
|
||||||
|
// cursor: not-allowed;
|
||||||
|
// }
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
.github-button,
|
|
||||||
.google-button {
|
|
||||||
@include themify() {
|
|
||||||
@extend %button;
|
|
||||||
& path {
|
|
||||||
color: getThemifyVariable('primary-text-color');
|
|
||||||
}
|
|
||||||
&:hover path, &:active path {
|
|
||||||
fill: $white;
|
|
||||||
}
|
|
||||||
&:hover, &:active {
|
|
||||||
color: getThemifyVariable('button-hover-color');
|
|
||||||
background-color: getThemifyVariable('button-background-hover-color');
|
|
||||||
border-color: getThemifyVariable('button-background-hover-color');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
width: #{300 / $base-font-size}rem;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
& + & {
|
|
||||||
margin-top: #{10 / $base-font-size}rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.github-icon {
|
|
||||||
margin-right: #{10 / $base-font-size}rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.google-icon {
|
|
||||||
width: #{32 / $base-font-size}rem;
|
|
||||||
height: #{32 / $base-font-size}rem;
|
|
||||||
margin-right: #{10 / $base-font-size}rem;
|
|
||||||
}
|
|
|
@ -31,7 +31,6 @@
|
||||||
@import 'components/resizer';
|
@import 'components/resizer';
|
||||||
@import 'components/overlay';
|
@import 'components/overlay';
|
||||||
@import 'components/about';
|
@import 'components/about';
|
||||||
@import 'components/github-button';
|
|
||||||
@import 'components/forms';
|
@import 'components/forms';
|
||||||
@import 'components/toast';
|
@import 'components/toast';
|
||||||
@import 'components/timer';
|
@import 'components/timer';
|
||||||
|
|
Loading…
Reference in a new issue