Skip to content

Commit c355408

Browse files
Finish Video
1 parent b5bff3b commit c355408

19 files changed

+1436
-251
lines changed

package-lock.json

Lines changed: 993 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@
66
"@testing-library/jest-dom": "^4.2.4",
77
"@testing-library/react": "^9.5.0",
88
"@testing-library/user-event": "^7.2.1",
9+
"bootstrap": "^4.5.2",
10+
"firebase": "^7.20.0",
911
"react": "^16.13.1",
12+
"react-bootstrap": "^1.3.0",
1013
"react-dom": "^16.13.1",
14+
"react-router-dom": "^5.2.0",
1115
"react-scripts": "3.4.3"
1216
},
1317
"scripts": {

src/App.css

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/App.js

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/App.test.js

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/components/App.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from "react"
2+
import Signup from "./Signup"
3+
import { Container } from "react-bootstrap"
4+
import { AuthProvider } from "../contexts/AuthContext"
5+
import { BrowserRouter as Router, Switch, Route } from "react-router-dom"
6+
import Dashboard from "./Dashboard"
7+
import Login from "./Login"
8+
import PrivateRoute from "./PrivateRoute"
9+
import ForgotPassword from "./ForgotPassword"
10+
import UpdateProfile from "./UpdateProfile"
11+
12+
function App() {
13+
return (
14+
<Container
15+
className="d-flex align-items-center justify-content-center"
16+
style={{ minHeight: "100vh" }}
17+
>
18+
<div className="w-100" style={{ maxWidth: "400px" }}>
19+
<Router>
20+
<AuthProvider>
21+
<Switch>
22+
<PrivateRoute exact path="/" component={Dashboard} />
23+
<PrivateRoute path="/update-profile" component={UpdateProfile} />
24+
<Route path="/signup" component={Signup} />
25+
<Route path="/login" component={Login} />
26+
<Route path="/forgot-password" component={ForgotPassword} />
27+
</Switch>
28+
</AuthProvider>
29+
</Router>
30+
</div>
31+
</Container>
32+
)
33+
}
34+
35+
export default App

src/components/Dashboard.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React, { useState } from "react"
2+
import { Card, Button, Alert } from "react-bootstrap"
3+
import { useAuth } from "../contexts/AuthContext"
4+
import { Link, useHistory } from "react-router-dom"
5+
6+
export default function Dashboard() {
7+
const [error, setError] = useState("")
8+
const { currentUser, logout } = useAuth()
9+
const history = useHistory()
10+
11+
async function handleLogout() {
12+
setError("")
13+
14+
try {
15+
await logout()
16+
history.push("/login")
17+
} catch {
18+
setError("Failed to log out")
19+
}
20+
}
21+
22+
return (
23+
<>
24+
<Card>
25+
<Card.Body>
26+
<h2 className="text-center mb-4">Profile</h2>
27+
{error && <Alert variant="danger">{error}</Alert>}
28+
<strong>Email:</strong> {currentUser.email}
29+
<Link to="/update-profile" className="btn btn-primary w-100 mt-3">
30+
Update Profile
31+
</Link>
32+
</Card.Body>
33+
</Card>
34+
<div className="w-100 text-center mt-2">
35+
<Button variant="link" onClick={handleLogout}>
36+
Log Out
37+
</Button>
38+
</div>
39+
</>
40+
)
41+
}

src/components/ForgotPassword.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React, { useRef, useState } from "react"
2+
import { Form, Button, Card, Alert } from "react-bootstrap"
3+
import { useAuth } from "../contexts/AuthContext"
4+
import { Link } from "react-router-dom"
5+
6+
export default function ForgotPassword() {
7+
const emailRef = useRef()
8+
const { resetPassword } = useAuth()
9+
const [error, setError] = useState("")
10+
const [message, setMessage] = useState("")
11+
const [loading, setLoading] = useState(false)
12+
13+
async function handleSubmit(e) {
14+
e.preventDefault()
15+
16+
try {
17+
setMessage("")
18+
setError("")
19+
setLoading(true)
20+
await resetPassword(emailRef.current.value)
21+
setMessage("Check your inbox for further instructions")
22+
} catch {
23+
setError("Failed to reset password")
24+
}
25+
26+
setLoading(false)
27+
}
28+
29+
return (
30+
<>
31+
<Card>
32+
<Card.Body>
33+
<h2 className="text-center mb-4">Password Reset</h2>
34+
{error && <Alert variant="danger">{error}</Alert>}
35+
{message && <Alert variant="success">{message}</Alert>}
36+
<Form onSubmit={handleSubmit}>
37+
<Form.Group id="email">
38+
<Form.Label>Email</Form.Label>
39+
<Form.Control type="email" ref={emailRef} required />
40+
</Form.Group>
41+
<Button disabled={loading} className="w-100" type="submit">
42+
Reset Password
43+
</Button>
44+
</Form>
45+
<div className="w-100 text-center mt-3">
46+
<Link to="/login">Login</Link>
47+
</div>
48+
</Card.Body>
49+
</Card>
50+
<div className="w-100 text-center mt-2">
51+
Need an account? <Link to="/signup">Sign Up</Link>
52+
</div>
53+
</>
54+
)
55+
}

src/components/Login.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React, { useRef, useState } from "react"
2+
import { Form, Button, Card, Alert } from "react-bootstrap"
3+
import { useAuth } from "../contexts/AuthContext"
4+
import { Link, useHistory } from "react-router-dom"
5+
6+
export default function Login() {
7+
const emailRef = useRef()
8+
const passwordRef = useRef()
9+
const { login } = useAuth()
10+
const [error, setError] = useState("")
11+
const [loading, setLoading] = useState(false)
12+
const history = useHistory()
13+
14+
async function handleSubmit(e) {
15+
e.preventDefault()
16+
17+
try {
18+
setError("")
19+
setLoading(true)
20+
await login(emailRef.current.value, passwordRef.current.value)
21+
history.push("/")
22+
} catch {
23+
setError("Failed to log in")
24+
}
25+
26+
setLoading(false)
27+
}
28+
29+
return (
30+
<>
31+
<Card>
32+
<Card.Body>
33+
<h2 className="text-center mb-4">Log In</h2>
34+
{error && <Alert variant="danger">{error}</Alert>}
35+
<Form onSubmit={handleSubmit}>
36+
<Form.Group id="email">
37+
<Form.Label>Email</Form.Label>
38+
<Form.Control type="email" ref={emailRef} required />
39+
</Form.Group>
40+
<Form.Group id="password">
41+
<Form.Label>Password</Form.Label>
42+
<Form.Control type="password" ref={passwordRef} required />
43+
</Form.Group>
44+
<Button disabled={loading} className="w-100" type="submit">
45+
Log In
46+
</Button>
47+
</Form>
48+
<div className="w-100 text-center mt-3">
49+
<Link to="/forgot-password">Forgot Password?</Link>
50+
</div>
51+
</Card.Body>
52+
</Card>
53+
<div className="w-100 text-center mt-2">
54+
Need an account? <Link to="/signup">Sign Up</Link>
55+
</div>
56+
</>
57+
)
58+
}

src/components/PrivateRoute.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from "react"
2+
import { Route, Redirect } from "react-router-dom"
3+
import { useAuth } from "../contexts/AuthContext"
4+
5+
export default function PrivateRoute({ component: Component, ...rest }) {
6+
const { currentUser } = useAuth()
7+
8+
return (
9+
<Route
10+
{...rest}
11+
render={props => {
12+
return currentUser ? <Component {...props} /> : <Redirect to="/login" />
13+
}}
14+
></Route>
15+
)
16+
}

0 commit comments

Comments
 (0)