0

I am new to nextJS (version: 13.4), and I want to use role-based authentication in my nextJS application, So in order to do that, I am using a higher-order component. In my scenario, I am able to handle only the static page route but I don't know how to handle the dynamic route.

What I have done so far:

In my application, I have created the route.ts file that contains all static routing paths depending on the user's role. I have imported this file into my higher-order component. The route.ts file provides access permissions for the static routing page. But I can't impose a dynamic path in the route.ts file, because I don't know what a dynamic route looks like. So that, I could not handle the dynamic route in the role-based authentication.

If you know how to handle them, please share them with me.

route.ts

interface HeaderNavItem {
  name: string;
  path: string;
}

interface Role {
  path: string[];
}

interface Roles {
  [key: string]: Role; // different key name
}

const roles: Roles = {
  superAdmin: {
    path: ["/", "/admin", "/superadmin", "/user"],
  },
  admin: {
    path: ["/", "/admin", "/user", "/admin/test"],
  },
  user: {
    path: ["/", "/user"],
  },
};

export default roles;

Higher-Order-Component

import React, { useEffect } from "react";
import { useRouter, usePathname } from "next/navigation";
import roles from "@/utils/rout"; 
import { isLoginReducer } from "@/redux/features/authSlice";
import { useDispatch, useSelector } from "react-redux";
import Loader from "@/components/elements/Loader";

const UseRoleHook = (Component: any) => {
  return function ProtectedRoute() {
    // Get user role and login status from Redux store
    const { role, isLogin } = useSelector(
      (state: { authPersistedReducer: { role: string; isLogin: boolean } }) =>
        state.authPersistedReducer
    );

    const dispatch = useDispatch();
    const pathname = usePathname();
    const router = useRouter();

    useEffect(() => {
      // Check if the user is not logged in
      if (!isLogin) {
        // If the role is "admin", "superAdmin", or "user", set login status to true and redirect to the home page
        if (role === "admin" || role === "superAdmin" || role === "user") {
          dispatch(isLoginReducer(true)); // Dispatch the action to update the login state
          router.push("/");
        } else {
          router.push("/login"); // Redirect the user to the login page if the role is not recognized
        }
      } else {
        // If the user is logged in
        // Check if the current pathname is allowed for the user's role
        if (!roles[role]?.path.includes(pathname)) {
          // If not allowed, throw an error indicating "Permission Denied"
          throw new Error("Permission Denied");
        } else {
          // If allowed, redirect the user to the current pathname
          router.push(pathname);
        }
      }
    }, [isLogin, role, pathname]);

    if (!roles[role]?.path.includes(pathname)) {
      // If not, return a loading spinner using the Loader component while the correct route is loaded
      return (
        // Or display a loading spinner or message
        <div className="w-full h-screen flex justify-center items-center">
          <Loader />
        </div>
      );
    }

    return <Component />;
  };
};

export default UseRoleHook;
Gibson
  • 82
  • 7

0 Answers0