-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add code of Authentication day to app
- Loading branch information
1 parent
7f078db
commit 3350d8b
Showing
8 changed files
with
201 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Link } from "react-router-dom"; | ||
import { useSelector, useDispatch } from "react-redux"; | ||
import { getUserProfile } from "../store/auth/selectors"; | ||
import { logout } from "../store/auth/slice"; | ||
import "./styles.css"; | ||
|
||
const Toolbar = () => { | ||
const user = useSelector(getUserProfile); | ||
const dispatch = useDispatch(); | ||
|
||
return ( | ||
<div className="toolbar"> | ||
<Link to="/" className="logo-link"> | ||
<h2>Codaisseur Coders Network!</h2> | ||
</Link> | ||
<div className="button-container"> | ||
{user ? ( | ||
<> | ||
<h4 className="welcome-text">Welcome {user.name}</h4> | ||
<button onClick={() => dispatch(logout())}>Logout</button> | ||
</> | ||
) : ( | ||
<Link to="/login"> | ||
<button>Login</button> | ||
</Link> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Toolbar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.toolbar { | ||
display: flex; | ||
justify-content: space-between; | ||
padding-right: 30px; | ||
padding-left: 30px; | ||
background-color: lightsalmon; | ||
} | ||
|
||
.button-container { | ||
display: flex; | ||
align-items: center; | ||
} | ||
|
||
.welcome-text { | ||
margin-right: 30px; | ||
} | ||
|
||
.logo-link { | ||
text-decoration: none; | ||
color: black; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// src/pages/LoginPage.js | ||
import React, { useState } from "react"; | ||
import { useDispatch, useSelector } from "react-redux"; | ||
import { useNavigate } from "react-router-dom"; | ||
import { login } from "../store/auth/actions"; | ||
import { getAuthLoading } from "../store/auth/selectors"; | ||
|
||
export default function LoginPage() { | ||
const [email, setEmail] = useState(""); | ||
const [password, setPassword] = useState(""); | ||
const dispatch = useDispatch(); | ||
const navigate = useNavigate(); | ||
|
||
const loading = useSelector(getAuthLoading); | ||
|
||
function handleSubmit(event) { | ||
event.preventDefault(); | ||
dispatch(login(email, password, navigate)); | ||
} | ||
|
||
return ( | ||
<div style={{ marginLeft: 30 }}> | ||
<h1>Login</h1> | ||
<form onSubmit={handleSubmit}> | ||
<p> | ||
<label> | ||
Email:{" "} | ||
<input | ||
type="email" | ||
value={email} | ||
onChange={(e) => setEmail(e.target.value)} | ||
/> | ||
</label> | ||
</p> | ||
<p> | ||
<label> | ||
Password:{" "} | ||
<input | ||
type="password" | ||
value={password} | ||
onChange={(e) => setPassword(e.target.value)} | ||
/> | ||
</label> | ||
</p> | ||
<p> | ||
<button type="submit">Login</button> | ||
</p> | ||
</form> | ||
{loading && "Loading..."} | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// src/store/auth/actions.js | ||
import axios from "axios"; | ||
import { API_URL } from "../../config"; | ||
import { startLoading, userLoggedIn } from "./slice"; | ||
// A thunk creator | ||
export const login = (email, password, navigate) => { | ||
return async function thunk(dispatch, getState) { | ||
try { | ||
dispatch(startLoading()); | ||
|
||
const response = await axios.post(`${API_URL}/login`, { | ||
email, | ||
password, | ||
}); | ||
|
||
const { jwt } = response.data; | ||
|
||
const profileResponse = await axios.get(`${API_URL}/me`, { | ||
headers: { authorization: `Bearer ${jwt}` }, | ||
}); | ||
|
||
localStorage.setItem("token", jwt); | ||
|
||
dispatch(userLoggedIn({ accessToken: jwt, user: profileResponse.data })); | ||
navigate("/"); | ||
} catch (e) { | ||
console.log("Error at login", e.message); | ||
} | ||
}; | ||
}; | ||
|
||
export const bootstrapLoginState = () => async (dispatch, getState) => { | ||
try { | ||
const token = localStorage.getItem("token"); | ||
|
||
if (!token) return; | ||
|
||
const response = await axios.get(`${API_URL}/me`, { | ||
headers: { authorization: `Bearer ${token}` }, | ||
}); | ||
|
||
dispatch(userLoggedIn({ accessToken: token, user: response.data })); | ||
} catch (e) { | ||
console.log(e.message); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const getUserProfile = (reduxState) => reduxState.auth.me; | ||
export const getAuthLoading = (reduxState) => reduxState.auth.loading; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { createSlice } from "@reduxjs/toolkit"; | ||
|
||
const initialState = { | ||
me: null, // the logged-in user | ||
accessToken: null, | ||
loading: false, | ||
}; | ||
|
||
export const authSlice = createSlice({ | ||
name: "auth", | ||
initialState, | ||
reducers: { | ||
startLoading: (state) => { | ||
state.loading = true; | ||
}, | ||
userLoggedIn: (state, action) => { | ||
state.me = action.payload.user; | ||
state.accessToken = action.payload.accessToken; | ||
state.loading = false; | ||
}, | ||
logout: (state) => { | ||
localStorage.removeItem("token"); | ||
// when we want to update the whole state | ||
// we can return a new object instead of updating | ||
// each key one by one | ||
return initialState; | ||
}, | ||
}, | ||
}); | ||
|
||
export const { startLoading, userLoggedIn, logout } = authSlice.actions; | ||
|
||
export default authSlice.reducer; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters