From 048a9d3a798e372cf556e927bf97e49d43367cb8 Mon Sep 17 00:00:00 2001 From: Thessa Kranendonk Date: Thu, 20 Oct 2022 12:53:50 -0400 Subject: [PATCH 1/2] Updated SignIn.jsx from class component to a functional component with hooks --- src/components/SignIn/SignIn.jsx | 238 +++++++++++++------------------ 1 file changed, 101 insertions(+), 137 deletions(-) diff --git a/src/components/SignIn/SignIn.jsx b/src/components/SignIn/SignIn.jsx index a501c78b..85d73474 100644 --- a/src/components/SignIn/SignIn.jsx +++ b/src/components/SignIn/SignIn.jsx @@ -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, @@ -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 ( -
-
- { - error && ( -
- } - /> -
- ) - } -
+
+
+
- - -
- - -

Login to your account

+ className="signin-logo-link" + href="/" + to="/" + > + + +
+ + +

Login to your account

+ { errorMessage &&
+

{errorMessage}

+
+ } -
- this.handleChange(val, 'username')} - autoComplete="username" - className="signin-username-form-group" - /> + + setUsername(val)} + autoComplete="username" + className="signin-username-form-group" + /> 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" + /> -

- Need an account? {' '} - - Signup - -

- -
-
+ className="signin-login-btn" + variant="primary" + loading={loading} + onClick={(e) => handleSubmit(e)} + > + Log In + +

+ Need an account? {' '} + + Signup + +

+ + + +
-
- ); - } + ); } - -SignIn.propTypes = { - store: PropTypes.objectOf(PropTypes.object).isRequired, -}; + + SignIn.propTypes = { + store: PropTypes.objectOf(PropTypes.object).isRequired, + }; export default ChrisStore.withStore(SignIn); + From fbcf51eabbcbf178471fee82e9a47d8fef44cb1a Mon Sep 17 00:00:00 2001 From: Thessa Kranendonk Date: Thu, 20 Oct 2022 12:54:44 -0400 Subject: [PATCH 2/2] Added a minor style change for the error message in the SignIn.jsx form --- src/components/SignIn/SignIn.css | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/SignIn/SignIn.css b/src/components/SignIn/SignIn.css index e38a23ac..cb42d95d 100644 --- a/src/components/SignIn/SignIn.css +++ b/src/components/SignIn/SignIn.css @@ -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 {