Skip to content

Instantly share code, notes, and snippets.

@aaronmcadam
Created November 19, 2018 16:37
Show Gist options
  • Save aaronmcadam/f2f35204c2346cd1203f871ab2f6aad8 to your computer and use it in GitHub Desktop.
Save aaronmcadam/f2f35204c2346cd1203f871ab2f6aad8 to your computer and use it in GitHub Desktop.
import * as React from 'react';
import { Link } from '@reach/router';
import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as yup from 'yup';
import * as R from 'ramda';
import {
Box,
Button,
Text,
TextInput,
Flex,
InlineNotice,
Notice,
} from '../alchemy';
import { IdentityPage } from './IdentityPage';
import { TokenConsumer } from '../TokenProvider';
import { IBoxProps } from '../../typings/alchemy';
export interface ISignInFormValues {
password: string;
username: string;
}
const validationSchema = yup.object().shape({
password: yup.string().required('password.required'),
username: yup
.string()
.required('username.required')
.email('username.invalid'),
});
const TextInputField = (props: any) => {
const { field, ...otherProps } = props;
return <TextInput {...field} {...otherProps} />;
};
const FormLabel = (props: any) => {
return <Text as="label" fontWeight="bold" mb={2} {...props} />;
};
function ErrorNotice(props: { message: string } & IBoxProps) {
const { message, ...otherProps } = props;
return (
<InlineNotice type="danger" {...otherProps}>
{message}
</InlineNotice>
);
}
export function GlobalErrorNotice(
props: { message: string | null } & IBoxProps,
) {
const { message, ...otherProps } = props;
if (R.isNil(message)) {
return null;
}
return <Notice title={props.message} type="danger" {...otherProps} />;
}
export function SignInPage() {
return (
<IdentityPage heading="Sign in to your account" title="Sign in to Insight">
<TokenConsumer>
{({ signIn, globalErrorMessage }) => {
return (
<Formik<ISignInFormValues>
onSubmit={signIn}
initialValues={{
password: '',
username: '',
}}
validateOnBlur={false}
validateOnChange={false}
validationSchema={validationSchema}
>
{props => {
const buttonCopy = props.isSubmitting
? 'Signing in...'
: 'Sign in';
return (
<>
<GlobalErrorNotice
data-testid="error-sign-in-global"
message={globalErrorMessage}
mb={3}
/>
<Box as={Form} data-testid="form-sign-in" width={1}>
<Flex flexDirection="column" mb={3}>
<FormLabel htmlFor="username" title="Email" mb={2}>
Email address
</FormLabel>
<Field
component={TextInputField}
data-testid="input-username"
name="username"
id="username"
placeholder="Email address"
width={1}
/>
<ErrorMessage name="username">
{message => (
<ErrorNotice
data-testid="error-sign-in-username"
message={message}
mt={2}
/>
)}
</ErrorMessage>
</Flex>
<Flex flexDirection="column" mb={3}>
<FormLabel htmlFor="password" title="Password" mb={2}>
Password
</FormLabel>
<Field
component={TextInputField}
data-testid="input-password"
type="password"
name="password"
id="password"
placeholder="Password"
width={1}
/>
<ErrorMessage name="password">
{message => (
<ErrorNotice
data-testid="error-sign-in-password"
message={message}
mt={2}
/>
)}
</ErrorMessage>
</Flex>
<Button
data-testid="button-submit"
type="submit"
variant="primary"
disabled={props.isSubmitting}
width={1}
>
{buttonCopy}
</Button>
</Box>
</>
);
}}
</Formik>
);
}}
</TokenConsumer>
<Box mt={3}>
<Link to="/begin_reset_password">Forgot your password?</Link>
</Box>
</IdentityPage>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment