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;