I am new to nextJS, and I want to create a role-based application I have used the App route with nextJS's latest version(13.4) in that application, So that I did the role-based authentication using a higher-order component, In my scenario when an unauthorized person wants to access the unauthorized page I navigate the user into a permission-denied page, But before navigation, the page that user wants access will appear just a second, in order to prevent that, I have used the loader. But I don't know if the loader only prevents this type of issue or if any other methods have. Is the loader approach appropriate for handling unauthorized page access?
Higher Order Component
import React, { useEffect } from "react";
import { useRouter, usePathname } from "next/navigation";
import roles from "@/utils/routs";
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;