Files:
App.js
import UserContext from "./userContext";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import './App.css';
//Importing components
import Registration from "./components/Registration";
import ProfileForm from "./components/ProfileForm";
import welcome from "./components/welcome";
import Navbar from "./components/Navigation"
import Form from "./components/Form";
import AllUsersList from "./components/AllUsersList";
import MainContent from "./components/MainContent";
import Users from "./components/Users";
import Ngos from "./components/Ngos";
import User from "./components/InfosUser";
import Ngo from "./components/InfosNgo";
import RouteForAll from "./components/RouteForAll";
import RouteOnlyForAdmins from "./components/RouteOnlyForAdmins";
import NoPermision from "./components/NoPermision";
import PageNotFound from "./components/PageNotFound";
import RedirectToNotFound from "./components/RedirectToNotFound";
const Main = () => {
return (<div className="parent">
<Navbar />
<Switch>
<RouteForAll exact path="/main" component={MainContent} />
<RouteForAll path="/users" component={Users} />
<RouteForAll path="/user/:id" component={User} />
<RouteForAll path="/ngos" component={Ngos} />
<RouteForAll path="/ngo/:id" component={Ngo} />
<RouteOnlyForAdmins path="/usersList" component={AllUsersList} />
<RouteForAll path="/profileform" component={ProfileForm} />
<Route component={RedirectToNotFound} />
</Switch>
</div>)
}
const App = () => {
const [user, setUser] = useState({});
const [tokens, setTokens] = useState({});
function loginTokens(tokens) {
setTokens(tokens);
}
function loginUser(user) {
setUser(user);
}
function logout() {
setUser({});
setTokens({});
}
return (
<UserContext.Provider
value={{
user: user,
tokens: tokens,
loginTokens: loginTokens,
loginUser: loginUser,
logout: logout
}}>
<div className="parent">
<Router>
<Switch>
<Route path="/notfound" component={PageNotFound} />
<Route exact path="/" component={welcome} />
<Route path="/login" component={Form} />
<Route path="/register" component={Registration} />
<RouteForAll path="/nopermision" component={NoPermision} />
<Route component={Main} />
</Switch>
</Router>
</div>
</UserContext.Provider>
);
};
export default App;
APIUtils.js
// this is our server and port address
// the base of all AJAX requests
const API_URL = "http://localhost:4321/";
export default class APIUtils {
static async get(url, access_token) {
return await issueAJAXRequest("GET", url, {}, access_token);
}
static async delete(url, access_token) {
return await issueAJAXRequest("DELETE", url, access_token);
}
static async post(url, data, access_token) {
return await issueAJAXRequest("POST", url, data, access_token);
}
static async put(url, data, access_token) {
return await issueAJAXRequest("PUT", url, data, access_token);
}
}
async function issueAJAXRequest(method, endpoint, body = {}, access_token = "") {
const params = { method };
params.headers = {
"Authorization": `Bearer ${access_token}`
};
if (Object.keys(body).length > 0) {
params.headers["Content-Type"] = "application/json; charset=utf-8";
params.body = JSON.stringify(body);
}
const res = await fetch(API_URL + endpoint, params);
if (!res.ok || res.status < 200 || res.status > 299) {
const errorMessage = `HTTP ${res.status} - ${res.statusText}`;
console.log(errorMessage);
throw new Error(errorMessage);
}
return await res.json();
}
UserProvider.js
export default class UserProvider {
static async getUsers(access_token) {
return await APIUtils.get("users/", access_token);
}
static async getUser(id, access_token) {
return await APIUtils.get(`users/${id}`, access_token);
}
static async createUser(userData) {
return await APIUtils.post("users/", userData);
}
static async updateUser(id, userData, access_token) {
return await APIUtils.put(`users/${id}`, userData, access_token);
}
static async deleteUser(id, access_token) {
return await APIUtils.delete(`users/${id}`, access_token);
}
static async loginUser(userData) {
return await APIUtils.post(`auth/login/`, userData);
}
}
userContext.js
export const UserContext = React.createContext({
user: {},
tokens: {},
loginTokens: tokens => {},
loginUser: user => {},
logout: () => {}
});
export default UserContext;
RouteForAll.js
import React, { useContext } from "react";
import { Route, Redirect } from "react-router-dom";
import UserContext from "../userContext";
import UserProvider from "../UserProvider";
const RouteForAll = ({ component: Component, ...rest }) => {
const user = useContext(UserContext);
const accessTkn = localStorage.getItem('access_token')
const refreshTkn = localStorage.getItem('refresh_token')
async function checkUser() {
try {
let payload = JSON.parse(atob(accessTkn.split(".")[1]));
const userData = await UserProvider.getUser(payload.id, accessTkn)
if (userData.error) { throw userData.error };
user.loginUser(userData);
return true;
}
catch (anError) {
console.log('Login Error:', anError);
}
}
return <Route {...rest} render={(props) => {
if (Object.keys(user.user).length &&
(user.user.user.role === "admin" ||
user.user.user.role === "user-independent" ||
user.user.user.role === "user-ngo"
)) { return <Component {...props} /> }
else if (accessTkn && refreshTkn) {
user.loginTokens({
access_token: accessTkn,
refresh_token: refreshTkn
});
if (checkUser()) { return <Component {...props} /> } else { return <Redirect to="/login" /> }
}
}} />
}
export default RouteForAll;
I tried with the code in RouteForAll but I've got the following error
"Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops."