Replace User form buttons with shared Button component

This commit is contained in:
Andrew Nicolaou 2020-04-19 22:45:09 +02:00
parent b61bd69505
commit 96ecb3e4a0
15 changed files with 129 additions and 118 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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>
); );
} }

View file

@ -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>
); );
} }

View file

@ -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>
); );
} }

View 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;

View 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>
);

View file

@ -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>
); );
} }

View file

@ -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>
); );

View file

@ -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&apos;t have an account?&nbsp; Don&apos;t have an account?&nbsp;
<Link className="form__signup-button" to="/signup">Sign Up</Link> <Link className="form__signup-button" to="/signup">Sign Up</Link>

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
// }

View file

@ -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;
}

View file

@ -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';