mirror of
https://github.com/rjNemo/devbook_ts
synced 2026-06-12 13:36:43 +00:00
sign in page functional
This commit is contained in:
parent
31013d573a
commit
c7f68469fe
3 changed files with 117 additions and 38 deletions
|
|
@ -2,9 +2,13 @@ import React, {FC} from 'react';
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||||
import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons';
|
import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
const Alert: FC = () => (
|
interface IProps {
|
||||||
|
text: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Alert: FC<IProps> = ({text}) => (
|
||||||
<div className="alert alert-danger">
|
<div className="alert alert-danger">
|
||||||
<FontAwesomeIcon icon={faExclamationTriangle} /> Passwords don't match!
|
<FontAwesomeIcon icon={faExclamationTriangle} /> {text}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,112 @@
|
||||||
import React, {FC} from 'react';
|
import React, {FC, useState} from 'react';
|
||||||
|
// Redux
|
||||||
|
import {compose} from '@reduxjs/toolkit';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import {WithFirebaseProps, withFirebase} from 'react-redux-firebase';
|
||||||
|
import {selectProfile} from '../store/firebase';
|
||||||
|
// Routing
|
||||||
|
import {Link, useHistory, Redirect} from 'react-router-dom';
|
||||||
import * as ROUTES from '../constants/routes';
|
import * as ROUTES from '../constants/routes';
|
||||||
|
// Style
|
||||||
|
import GoogleButton from 'react-google-button';
|
||||||
import Header from '../components/Header';
|
import Header from '../components/Header';
|
||||||
import {Link} from 'react-router-dom';
|
import Alert from '../components/Alert';
|
||||||
|
// Typing
|
||||||
|
import User from '../models/User';
|
||||||
|
// Form
|
||||||
|
import useForm from '../hooks';
|
||||||
|
|
||||||
|
interface InitFormData {
|
||||||
|
email: string;
|
||||||
|
password: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IProps extends WithFirebaseProps<User> {
|
||||||
|
isEmpty: boolean;
|
||||||
|
isLoaded: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sign in form
|
* Sign in form
|
||||||
*/
|
*/
|
||||||
const SignIn: FC = () => (
|
const SignIn: FC<IProps> = ({firebase, isEmpty, isLoaded}) => {
|
||||||
|
const history = useHistory();
|
||||||
|
const [error, setError] = useState<any>(null);
|
||||||
|
|
||||||
|
// handle form data
|
||||||
|
const initFormData: InitFormData = {
|
||||||
|
email: '',
|
||||||
|
password: '',
|
||||||
|
};
|
||||||
|
const {formData, handleChange, resetForm} = useForm<InitFormData>(
|
||||||
|
initFormData,
|
||||||
|
);
|
||||||
|
const {email, password} = formData;
|
||||||
|
|
||||||
|
// prevent submitting invalid forms
|
||||||
|
const isDisabled: boolean = email === '' || password === '';
|
||||||
|
|
||||||
|
/** create user with password */
|
||||||
|
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
firebase
|
||||||
|
.login({email, password})
|
||||||
|
.then(() => resetForm())
|
||||||
|
.catch(err => setError(err));
|
||||||
|
};
|
||||||
|
|
||||||
|
const loginWithGoogle = () =>
|
||||||
|
firebase.login({provider: 'google', type: 'popup'});
|
||||||
|
|
||||||
|
if (isLoaded && !isEmpty) {
|
||||||
|
return <Redirect to={ROUTES.DASHBOARD} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
<div className="alert alert-danger">Invalid credentials</div>
|
{error && <Alert text={error?.message} />}
|
||||||
<Header title="Sign In" lead="Sign into your account" />
|
<Header title="Sign In" lead="Sign into your account" />
|
||||||
<form action="dashboard.html" className="form">
|
<GoogleButton type="light" className="my-1" onClick={loginWithGoogle} />
|
||||||
|
<form onSubmit={handleSubmit} className="form">
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<input type="email" placeholder="Email Address" />
|
<input
|
||||||
|
name="email"
|
||||||
|
value={email}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder="Email Address"
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<input type="password" placeholder="Password" minLength={6} />
|
<input
|
||||||
|
name="password"
|
||||||
|
value={password}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder="Password"
|
||||||
|
type="password"
|
||||||
|
minLength={6}
|
||||||
|
required
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="submit" value="Login" className="btn btn-primary" />
|
<input
|
||||||
|
type="submit"
|
||||||
|
value="Login"
|
||||||
|
className="btn btn-primary"
|
||||||
|
disabled={isDisabled}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
<p className="my-1">
|
<p className="my-1">
|
||||||
Don't have an account? <Link to={ROUTES.SIGN_UP}>Sign up</Link>
|
Don't have an account? <Link to={ROUTES.SIGN_UP}>Sign up</Link>
|
||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default SignIn;
|
/** subscribe to store and firebase */
|
||||||
|
const enhance = compose<FC<IProps>>(connect(selectProfile), withFirebase);
|
||||||
|
|
||||||
|
export default enhance(SignIn);
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ interface InitFormData {
|
||||||
*/
|
*/
|
||||||
const SignUp: FC<IProps> = ({firebase, isEmpty, isLoaded}) => {
|
const SignUp: FC<IProps> = ({firebase, isEmpty, isLoaded}) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState<any>(null);
|
||||||
|
|
||||||
// handle form data
|
// handle form data
|
||||||
const initFormData: InitFormData = {
|
const initFormData: InitFormData = {
|
||||||
|
|
@ -55,19 +55,11 @@ const SignUp: FC<IProps> = ({firebase, isEmpty, isLoaded}) => {
|
||||||
/** create user with password */
|
/** create user with password */
|
||||||
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (password !== password2) {
|
|
||||||
setError(true);
|
|
||||||
} else {
|
|
||||||
// pass the info to store into the second argument
|
// pass the info to store into the second argument
|
||||||
firebase
|
firebase
|
||||||
.createUser({email, password}, newUser(name, email))
|
.createUser({email, password}, newUser(name, email))
|
||||||
.then(() => {
|
.then(() => resetForm())
|
||||||
resetForm();
|
.catch(err => setError(err));
|
||||||
// redirect to dashboard
|
|
||||||
history.push(ROUTES.DASHBOARD);
|
|
||||||
})
|
|
||||||
.catch(err => console.error(err));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const loginWithGoogle = () =>
|
const loginWithGoogle = () =>
|
||||||
|
|
@ -79,7 +71,7 @@ const SignUp: FC<IProps> = ({firebase, isEmpty, isLoaded}) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="container">
|
<section className="container">
|
||||||
{error && <Alert />}
|
{error && <Alert text={error?.message} />}
|
||||||
<Header title="Sign Up" lead="Create your account" />
|
<Header title="Sign Up" lead="Create your account" />
|
||||||
<GoogleButton type="light" className="my-1" onClick={loginWithGoogle} />
|
<GoogleButton type="light" className="my-1" onClick={loginWithGoogle} />
|
||||||
<form className="form" onSubmit={handleSubmit}>
|
<form className="form" onSubmit={handleSubmit}>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue