Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions src/components/SignIn/SignIn.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@
min-width: 320px;
}

.signin-error-container {
padding-top: 1em;
}

.signin-error-container .signin-error {
margin-bottom: 0;
.signin-error-message {
padding: 0 0 2rem 2rem;
color: red;
font-weight: 600;
}

.signin-logo-container {
Expand Down
238 changes: 101 additions & 137 deletions src/components/SignIn/SignIn.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import React, { Component } from 'react';
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import StoreClient from '@fnndsc/chrisstoreapi';
import {
Form,
Alert,
AlertActionCloseButton,
CardTitle,
Card,
CardBody,
Expand All @@ -17,151 +15,117 @@ import chrisLogo from '../../assets/img/chris_logo-white.png';
import ChrisStore from '../../store/ChrisStore';
import FormInput from '../FormInput';

export class SignIn extends Component {
constructor(props) {
super(props);
const SignIn = (props) => {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const [errorMessage, setErrorMessage] = useState(null)

this.state = {
username: '',
password: '',
loading: false,
error: null,
};

this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.showError = this.showError.bind(this);
this.hideError = this.hideError.bind(this);
}

componentDidMount() {
// if the user attempts to see the login page when they are
// already logged in, we will log them out.
// TODO SECURITY idk if safe from CSRF
// TODO SECURITY send goodbye to backend to invalidate authToken
const { store } = this.props;
if (store.get('isLoggedIn')) {
store.set('authToken')('');
}
}

handleChange(value, name) {
this.setState({ [name]: value });
}
useEffect(() => {
// if the user attempts to see the login page when they are
// already logged in, we will log them out.
// TODO SECURITY idk if safe from CSRF
// TODO SECURITY send goodbye to backend to invalidate authToken
const { store } = props;
if (store.get('isLoggedIn')) {
store.set('authToken')('');
}
});

async handleSubmit(event) {
const authURL = process.env.REACT_APP_STORE_AUTH_URL;
const { username, password } = this.state;
const { store, location, history } = this.props;
this.setState({ loading: true });
try {
const token = await StoreClient.getAuthToken(authURL, username, password);
store.set('userName')(username);
store.set('authToken')(token);
this.setState({ loading: false });
async function handleSubmit(event) {
event.preventDefault()
const authURL = process.env.REACT_APP_STORE_AUTH_URL;
const { store, location, history } = props;
setLoading(true);

if (location.state && location.state.from)
history.replace(location.state.from);
else
history.push('/dashboard');
} catch (error) {
this.showError('Invalid username or password');
this.setState({ loading: false });
try {
const token = await StoreClient.getAuthToken(authURL, username, password);
store.set('userName')(username);
store.set('authToken')(token);
setLoading(false);

if (location.state && location.state.from)
history.replace(location.state.from);
else
history.push('/dashboard');
} catch (error) {
setErrorMessage('Invalid username or password');
setLoading(false);
}
event.persist();
}
event.persist();
}

showError(message) {
this.setState({ error: message });
}

hideError() {
this.setState({ error: null });
}
render() {
const {
error, username, password, loading,
} = this.state;


return (
<div className="signin login-pf-page">
<div className="signin-container">
{
error && (
<div className="signin-error-container">
<Alert
className="signin-error"
variant="danger"
title={error}
actionClose={<AlertActionCloseButton onClose={this.hideError} />}
/>
</div>
)
}
<div className="signin-logo-container">
<div className="signin login-pf-page">
<div className="signin-container">
<div className="signin-logo-container">
<Link
className="signin-logo-link"
href="/"
to="/"
>
<img
className="signin-logo"
src={chrisLogo}
alt=""
/>
</Link>
</div>
<Card className="signin-card">
<CardTitle className="login-pf-page-header">
<h1>Login to your account</h1>
className="signin-logo-link"
href="/"
to="/"
>
<img
className="signin-logo"
src={chrisLogo}
alt=""
/>
</Link>
</div>
<Card className="signin-card">
<CardTitle className="login-pf-page-header">
<h1>Login to your account</h1>
</CardTitle>
{ errorMessage && <div className='signin-error-message'>
<p>{errorMessage}</p>
</div>
}
<CardBody>
<Form className="signin-form">
<FormInput
placeholder="Username"
fieldName="username"
id="username"
inputType="text"
value={username}
onChange={(val) => this.handleChange(val, 'username')}
autoComplete="username"
className="signin-username-form-group"
/>
<Form className="signin-form">
<FormInput
placeholder="Username"
fieldName="username"
id="username"
inputType="text"
value={username}
onChange={(val) => setUsername(val)}
autoComplete="username"
className="signin-username-form-group"
/>
<FormInput
placeholder="Password"
fieldName="password"
value={password}
inputType="password"
id="password"
onChange={(val) => this.handleChange(val, 'password')}
autoComplete="current-password"
className="signin-password-form-group"
/>
placeholder="Password"
fieldName="password"
value={password}
inputType="password"
id="password"
onChange={(val) => setPassword(val)}
autoComplete="current-password"
className="signin-password-form-group"
/>
<Button
className="signin-login-btn"
variant="primary"
loading={loading}
onClick={this.handleSubmit}
>
Log In
</Button>
<p className="login-pf-signup">
Need an account? {' '}
<Link to="/quickstart" href="/quickstart">
Signup
</Link>
</p>
</Form>
</CardBody>
</Card>
className="signin-login-btn"
variant="primary"
loading={loading}
onClick={(e) => handleSubmit(e)}
>
Log In
</Button>
<p className="login-pf-signup">
Need an account? {' '}
<Link to="/quickstart" href="/quickstart">
Signup
</Link>
</p>
</Form>
</CardBody>
</Card>
</div>
</div>
</div>
);
}
);
}

SignIn.propTypes = {
store: PropTypes.objectOf(PropTypes.object).isRequired,
};
SignIn.propTypes = {
store: PropTypes.objectOf(PropTypes.object).isRequired,
};

export default ChrisStore.withStore(SignIn);