-1

Here is the protected route where I have checked for isAuthenticated. The isAuthenticated status is managed by Redux. When there is no token saved in local storage, isAuthenticated is set to false. This is for protective routes:

import PropTypes from "prop-types";
import { useEffect } from "react";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { RootState } from "src/store";

const ProtectedRoute = ({ children }) => {
  const navigate = useNavigate();
  const { isAuthenticated } = useSelector((state: RootState) => state.login);

  useEffect(() => {
    if (!isAuthenticated) {
      navigate("/");
    }
  }, [isAuthenticated]);
  return children;
};

ProtectedRoute.propTypes = {
  children: PropTypes.node.isRequired,
};

export default ProtectedRoute;

Logic to check user permission:

import { ReactNode, Fragment } from "react";
import { Navigate } from "react-router-dom";
import { useUserRoles } from "src/utils/ToastMessage";

interface RolesAuthRouteProps {
  children: ReactNode;
  roles: Array<string>;
}

export function RolesAuthRoute({ children, roles }: RolesAuthRouteProps) {
  const userRoles = useUserRoles();

  const canAccess = userRoles.some(userRole => roles.includes(userRole));

  if (canAccess) return <>{children}</>;

  return <Navigate to="/" />;
}

Logic to check unprotected route:

import { useSelector } from "react-redux";
import { Navigate, Outlet } from "react-router-dom";

import { RootState } from "src/store";

const UnProtectedRoute = () => {
  const { isAuthenticated } = useSelector((state: RootState) => state.login);
  return isAuthenticated ? <Navigate to="/dashboard" replace /> : <Outlet />;
};

export default UnProtectedRoute;

Here I have defined all routes:

  <BrowserRouter>
    <Routes>
      <Route element={<UnProtectedRoute />}>
        <Route element={<Login />} path="/" />
      </Route>

      <Route
        path="dashboard"
        element={
          <ProtectedRoute>
            <RolesAuthRoute roles={["admin"]}>
              <Dashboard />
            </RolesAuthRoute>
          </ProtectedRoute>
        }
      />
      <Route
        path="reports"
        element={
          <ProtectedRoute>
            <RolesAuthRoute roles={["admin"]}>
              <DashboardDetails />
            </RolesAuthRoute>
          </ProtectedRoute>
        }
      />
    </Routes>
  </BrowserRouter>

ToastMessage.tsx

export type UserRole = "admin" | "root" | "user";

export function useUserRoles() {
  // some logic or api call to get the roles
  // for demonstration purposes it's just hard coded
  const userRoles: UserRole[] = ["admin", "root"];

  // return the current user roles
  return userRoles;
}

When I attempt to navigate to reports, only dashboard links are rendered. I am unable to access other protected routes.

Shiva Giri
  • 105
  • 1
  • 6
  • Is this `import { useUserRoles } from "src/utils/ToastMessage";` import correct? Does this help answer your question about protected routes implementation? https://stackoverflow.com/questions/66289122/how-to-create-a-protected-route-with-react-router-dom Can you [edit] to clarify what links you are referring to? See [mcve]. – Drew Reese Aug 10 '23 at 17:34
  • After adding links to the items in the dashboard menu list, it began functioning perfectly – Shiva Giri Aug 11 '23 at 02:12

1 Answers1

-1

I've used this method and works:

create a function to export your authenticated routes in my case is called AppRoutes and another function to export the unauthenticated routes in case is called AuthRoutes.

enter image description here

In your App.tsx

return (

    <NavigationContainer>
      <Routes />
    </NavigationContainer>
)

I hope this may help you.

Rodrigo Dias
  • 114
  • 1
  • 9