File tree Expand file tree Collapse file tree 6 files changed +131
-5
lines changed
Expand file tree Collapse file tree 6 files changed +131
-5
lines changed Original file line number Diff line number Diff line change @@ -10,12 +10,16 @@ import { NewProducts } from './components/NewProducts';
1010import { Users } from './components/Users' ;
1111import { UserDetails } from './components/UserDetails' ;
1212import { Admin } from './components/Admin' ;
13+ import { Profile } from './components/Profile' ;
14+ import { AuthProvider } from './components/Auth' ;
15+ import { Login } from './components/Login' ;
16+ import { RequireAuth } from './components/RequireAuth' ;
1317
1418function App ( ) {
1519 return (
16- < >
20+ < AuthProvider >
1721 < Navbar />
18- < Routes >
22+ < Routes >
1923 < Route path = '/' element = { < Home /> } > </ Route >
2024 < Route path = 'about' element = { < About /> } > </ Route >
2125 < Route path = 'order-summary' element = { < OrderSummary /> } > </ Route >
@@ -30,10 +34,18 @@ function App() {
3034 < Route path = ':userId' element = { < UserDetails /> } />
3135 < Route path = 'admin' element = { < Admin /> } />
3236 </ Route >
33-
37+ < Route
38+ path = 'profile'
39+ element = {
40+ < RequireAuth >
41+ < Profile />
42+ </ RequireAuth >
43+ }
44+ />
45+ < Route path = 'login' element = { < Login /> } />
3446 < Route path = '*' element = { < NoMatch /> } > </ Route >
35- </ Routes >
36- </ >
47+ </ Routes >
48+ </ AuthProvider >
3749 ) ;
3850}
3951
Original file line number Diff line number Diff line change 1+ import { useState , createContext , useContext } from "react"
2+
3+ const AuthContext = createContext ( null )
4+
5+ export const AuthProvider = ( { children } ) => {
6+ const [ user , setUser ] = useState ( null )
7+
8+ const login = ( user ) => {
9+ setUser ( user )
10+ }
11+
12+ const logout = ( ) => {
13+ setUser ( null )
14+ }
15+
16+ return (
17+ < AuthContext . Provider value = { { user, login, logout } } >
18+ { children }
19+ </ AuthContext . Provider >
20+ )
21+ }
22+
23+ // Function that returns the value of Auth Context
24+ export const useAuth = ( ) => {
25+ return useContext ( AuthContext )
26+ }
Original file line number Diff line number Diff line change 1+ import { useState } from 'react'
2+ import { useNavigate , useLocation } from 'react-router-dom'
3+ import { useAuth } from './Auth'
4+
5+ export const Login = ( ) => {
6+
7+ const [ user , setUser ] = useState ( '' )
8+ const auth = useAuth ( )
9+ const navigate = useNavigate ( )
10+ const location = useLocation ( )
11+
12+ const redirectPath = location . state ?. path || '/'
13+
14+ const handleLogin = ( ) => {
15+ auth . login ( user )
16+ // Once we set the username, we navigate the user to the home page.
17+ navigate ( redirectPath , { replace :true } )
18+ }
19+
20+ return (
21+ < div >
22+ < label >
23+ Username:
24+ < input type = 'text' onChange = { ( e ) => setUser ( e . target . value ) } />
25+ </ label >
26+ < button onClick = { handleLogin } > Login</ button >
27+ </ div >
28+ )
29+ }
30+
Original file line number Diff line number Diff line change 11import React from 'react'
22import { NavLink } from 'react-router-dom'
3+ import { useAuth } from './Auth'
34
45export const Navbar = ( ) => {
56
@@ -10,6 +11,8 @@ export const Navbar = () => {
1011 }
1112 }
1213
14+ const auth = useAuth ( )
15+
1316
1417 return (
1518 < nav className = 'primary-nav' >
@@ -22,6 +25,16 @@ export const Navbar = () => {
2225 < NavLink style = { navLinkStyles } to = 'products' >
2326 Products
2427 </ NavLink >
28+ < NavLink style = { navLinkStyles } to = 'profile' >
29+ Profile
30+ </ NavLink >
31+ {
32+ ! auth . user && (
33+ < NavLink style = { navLinkStyles } to = 'login' >
34+ Login
35+ </ NavLink >
36+ )
37+ }
2538 </ nav >
2639 )
2740}
Original file line number Diff line number Diff line change 1+ // Let's display the logged in username in the profile component & also addd a logout button.
2+
3+ import React from 'react'
4+ import { useAuth } from './Auth'
5+ import { useNavigate } from 'react-router-dom'
6+
7+ export const Profile = ( ) => {
8+
9+ const auth = useAuth ( )
10+ const navigate = useNavigate ( )
11+
12+ const handleLogout = ( ) => {
13+ auth . logout ( )
14+ // After logging out, we redirect the user to the home page
15+ navigate ( '/' )
16+ }
17+
18+ return < div > Welcome { auth . user }
19+ < button onClick = { handleLogout } > Logout</ button > </ div >
20+ }
21+
22+
Original file line number Diff line number Diff line change 1+ // NOTE - This file ensures that the Profile component is protected.
2+ // Below, we're creating a reusable wrapper component that decides
3+ // if the component can be rendered or if the user has to login first.
4+
5+ import { useAuth } from "./Auth" ;
6+ import { Navigate , useLocation } from "react-router-dom" ;
7+
8+
9+
10+ export const RequireAuth = ( { children } ) => {
11+
12+ const auth = useAuth ( )
13+ const location = useLocation ( )
14+
15+ // If the user is not logged in, it redirects to the login route.
16+ if ( ! auth . user ) {
17+ return < Navigate to = '/login' state = { { path :location . pathname } } />
18+ }
19+
20+ // If the user is logged in, it renders the children prop
21+ return children
22+ }
23+
You can’t perform that action at this time.
0 commit comments