Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rob Salzberg - React & Firebase Tutorial #2

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
14,826 changes: 0 additions & 14,826 deletions package-lock.json

This file was deleted.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"firebase": "^5.8.4",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1"
"react-router-dom": "^4.3.1",
"react-scripts": "2.1.1",
"recompose": "^0.30.0"
},
"scripts": {
"start": "react-scripts start",
Expand Down
30 changes: 27 additions & 3 deletions src/components/App/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';

import Navigation from '../Navigation';
import LandingPage from '../Landing';
import SignUpPage from '../SignUp';
import SignInPage from '../SignIn';
import PasswordForgetPage from '../PasswordForget';
import HomePage from '../Home';
import AccountPage from '../Account';
import AdminPage from '../Admin';

import * as ROUTES from '../../constants/routes';

const App = () => (
<div>
<h1>App</h1>
</div>
<Router>
<div>
<Navigation />

<hr />

<Route exact path={ROUTES.LANDING} component={LandingPage} />
<Route path={ROUTES.SIGN_UP} component={SignUpPage} />
<Route path={ROUTES.SIGN_IN} component={SignInPage} />
<Route path={ROUTES.PASSWORD_FORGET} component={PasswordForgetPage} />
<Route path={ROUTES.HOME} component={HomePage} />
<Route path={ROUTES.ACCOUNT} component={AccountPage} />
<Route path={ROUTES.ADMIN} component={AdminPage} />
</div>
</Router>
);

export default App;
11 changes: 11 additions & 0 deletions src/components/Firebase/context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

const FirebaseContext = React.createContext(null);

export const withFirebase = Component => props => (
<FirebaseContext.Consumer>
{firebase => <Component {...props} firebase={firebase} />}
</FirebaseContext.Consumer>
);

export default FirebaseContext;
36 changes: 36 additions & 0 deletions src/components/Firebase/firebase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import app from 'firebase/app';
import 'firebase/auth';

const config = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
databaseURL: process.env.REACT_APP_DATABASE_URL,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
};

class Firebase {
constructor() {
app.initializeApp(config);

this.auth = app.auth();
}

// *** Auth API ***
doCreateUserWithEmailAndPassword = (email, password) =>
this.auth.createUserWithEmailAndPassword(email, password);

doSignInWithEmailAndPassword = (email, password) =>
this.auth.signInWithEmailAndPassword(email, password);

doSignOut = () => this.auth.signOut();

doPasswordReset = email => this.auth.sendPasswordResetEmail(email);

doPasswordUpdate = password =>
this.auth.currentUser.updatePassword(password);

}

export default Firebase;
12 changes: 5 additions & 7 deletions src/components/Firebase/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import React from 'react';

const Firebase = () => (
<div>
<h1>Firebase</h1>
</div>
);
import FirebaseContext, { withFirebase } from './context';
import Firebase from './firebase';

export default Firebase;

export { FirebaseContext, withFirebase };

21 changes: 20 additions & 1 deletion src/components/Navigation/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
import React from 'react';
import {Link} from 'react-router-dom';

import * as ROUTES from '../../constants/routes';

const Navigation = () => (
<div>
<h1>Navigation</h1>
<ul>
<li>
<Link to={ROUTES.SIGN_IN}>Sign In</Link>
</li>
<li>
<Link to={ROUTES.LANDING}>Landing</Link>
</li>
<li>
<Link to={ROUTES.HOME}>Home</Link>
</li>
<li>
<Link to={ROUTES.ACCOUNT}>Account</Link>
</li>
<li>
<Link to={ROUTES.ADMIN}>Admin</Link>
</li>
</ul>
</div>
);

Expand Down
115 changes: 112 additions & 3 deletions src/components/SignUp/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,118 @@
import React from 'react';
import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom';
import { compose } from 'recompose';

const SignUp = () => (
import { withFirebase } from '../Firebase';
import * as ROUTES from '../../constants/routes';

const SignUpPage = () => (
<div>
<h1>SignUp</h1>
<SignUpForm />}
</div>
);

export default SignUp;
const INITIAL_STATE = {
username: '',
email: '',
passwordOne: '',
passwordTwo: '',
error: null,
};

class SignUpFormBase extends Component {
constructor(props) {
super(props);

this.state = { ...INITIAL_STATE };
}

onSubmit = event => {
const { username, email, passwordOne } = this.state;

this.props.firebase
.doCreateUserWithEmailAndPassword(email, passwordOne)
.then(authUser => {
this.setState({ ...INITIAL_STATE });
this.props.history.push(ROUTES.HOME);
})
.catch(error => {
this.setState({ error });
});

event.preventDefault();
};

onChange = event => {
this.setState({ [event.target.name]: event.target.value });
};

render() {
const {
username,
email,
passwordOne,
passwordTwo,
error,
} = this.state;

const isInvalid =
passwordOne !== passwordTwo ||
passwordOne === '' ||
email === '' ||
username === '';

return (
<form onSubmit={this.onSubmit}>
<input
name="username"
value={username}
onChange={this.onChange}
type="text"
placeholder="Full Name"
/>
<input
name="email"
value={email}
onChange={this.onChange}
type="text"
placeholder="Email Address"
/>
<input
name="passwordOne"
value={passwordOne}
onChange={this.onChange}
type="password"
placeholder="Password"
/>
<input
name="passwordTwo"
value={passwordTwo}
onChange={this.onChange}
type="password"
placeholder="Confirm Password"
/>
<button disabled={isInvalid} type="submit">
Sign Up
</button>

{error && <p>{error.message}</p>}
</form>
);
}
}

const SignUpLink = () => (
<p>
Don't have an account? <Link to={ROUTES.SIGN_UP}>Sign Up</Link>
</p>
);

const SignUpForm = compose(
withRouter,
withFirebase,)
(SignUpFormBase);

export default SignUpPage;

export { SignUpForm, SignUpLink };
7 changes: 7 additions & 0 deletions src/constants/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const LANDING = '/';
export const SIGN_UP = '/signup';
export const SIGN_IN = '/signin';
export const HOME = '/home';
export const ACCOUNT = '/account';
export const ADMIN = '/admin';
export const PASSWORD_FORGET = '/pw-forget';
11 changes: 7 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import './index.css';
import * as serviceWorker from './serviceWorker';

import App from './components/App';
import Firebase, { FirebaseContext } from './components/Firebase';

ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.render(
<FirebaseContext.Provider value={new Firebase()}>
<App />
</FirebaseContext.Provider>,
document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();
Loading