Asking
Asking

Reputation: 4192

Add react routes in application

I implemented some routes in my application:

  <Router>
        <Switch>
          <UnAuthRoute path="/login">
            <Login />
          </UnAuthRoute>
          <RoleRoute path={"/"}>
            <User />
          </RoleRoute>
          <RoleRoute path={"/admin"}>
            <Admin />
          </RoleRoute>
          <Route path="*" />
        </Switch>
      </Router>

This routes should respect next conditions:

If user access the application he should be redirected on route -> "/user"
If user try to access the route -> "/admin " he should be redirected on "/404"
If admin access the application he should be redirected on route -> "/admin "
If admin try to access the route -> "/user" he should be redirected on "/404"
If both users try to access "/login", and they are in application they should be redirected on their personal route

But i cant figure out why the app does not work. I tried to simulate my app: https://codesandbox.io/s/bold-mclaren-9vsvh?file=/src/App.js:371-706
How to fix the code to fit the conditions?

Upvotes: 0

Views: 80

Answers (3)

webcoder
webcoder

Reputation: 1517

you can also do like this

export const AdminRoute = ({ component: Component, ...rest }) => {
  const user = JSON.parse(localStorage.getItem("user"));
  return (
    <Route
      {...rest}
      render={(props) => {
        if (user.role === "Admin") {
          return <Component {...props} />;
        } else {
          return (
            <Redirect
              to={{
                pathname: "/",
                state: {
                  from: props.location,
                },
              }}
            />
          );
        }
      }}
    />
  );
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

and then

<AdminRoute exact path="/file-upload" component={FileUpload} />

Upvotes: 0

gdh
gdh

Reputation: 13692

You need to make few changes to your code to get your requirements working.

  • in RoleRoute.js you were comparing "undefined" with null(when localStorage.getItem returns null), so you were always redirected to 404. Correct way is to compare with null. Like this:
const authenticated = localStorage.getItem("mytoken") !== null;
  • put exact to / route
  • make sure to pass role prop

Working copy of your code is here in the sandbox

Route code snippet

    <div className="App">
      <Router>
        <Switch>
          <UnAuthRoute path="/login">
            <Login />
          </UnAuthRoute>
          <RoleRoute exact path={"/"} rolez="user">
            <User />
          </RoleRoute>
          <RoleRoute path={"/user"} rolez="user">
            <User />
          </RoleRoute>
          <RoleRoute path={"/admin"} rolez="admin">
            <Admin />
          </RoleRoute>
          <Route path="*" />
        </Switch>
      </Router>
    </div>

RoleRoute code snippet

import { Route, Redirect } from "react-router-dom";

export const RoleRoute = ({ children, redirectTo, path, rolez }) => {
  const authenticated = localStorage.getItem("mytoken") !== null;
  const allowed = localStorage.getItem("role") === rolez;

  if (!authenticated) return <Redirect to={redirectTo || "/login"} />;
  else if (allowed) return <Route path={path}>{children}</Route>;
  else return <Redirect to={redirectTo || "/404"} />;
};

Upvotes: 2

Milos
Milos

Reputation: 619

First of all you need to declare some roles. One for admin, second for regular user and third for non registered user. After that you need to specify the routes for each user

<Route exact path="/" component={() => isLoggedIn ? 
      isAdmin ? <Redirect to="/admin" /> : <Redirect to="/user" />
      : <Redirect to="/login" />
} />

Upvotes: 1

Related Questions