Somehow I came to a problem of thinking of how to make that if the person clicks on a link, it should be redirected to sign-in page if not authorized and to that page if authorized. This sounds easy, but the problem is that I want to make that if the user redirected to one page where it should be authorized, the user authorizes and redirect to the same page as he clicked.
For now, I have a protected route that looks like this: (I have fromPath argument for next redirection but that does not work for me.)
const ProtectedRoute = ({
isAllowed,
redirectPath = "/sign-in",
fromPath = null,
children,
}) => {
const dispatch = useDispatch();
if (fromPath) dispatch(setURLPath(fromPath));
if (!isAllowed) {
return <Navigate to={fromPath} replace />;
}
return children ? children : <Outlet />;
};
And here how it looks from the App.js side:
<Suspense fallback={<Spinner />}>
<GlobalStyle />
<Routes>
<Route
path='/'
element={
<ProtectedRoute
isAllowed={roleLevel > 0}
/>
}
>
<Route path='bookings' element={<BookingsPage />} />
<Route path='single-booking/:id' element={<SingleBookingPage />} />
<Route path='documents' element={<DocumentsPage />} />
<Route path='my-account' element={<MyAccountPage />} />
<Route path='reservation' element={<ReservationPage />} />
</Route>
</Route>
<Route path='*' element={<NotFoundPage />} />
</Routes>
</Suspense>
The ProtectedRoute component should grab the current location object for the route being accessed and pass this in route state to the login route.
import { useLocation } from 'react-router-dom';
const ProtectedRoute = ({
isAllowed,
redirectPath = "/sign-in",
fromPath = null,
children,
}) => {
const location = useLocation();
const dispatch = useDispatch();
if (fromPath) dispatch(setURLPath(fromPath));
if (!isAllowed) {
return <Navigate to={fromPath} replace state={{ from: location }} />;
}
return children ? children : <Outlet />;
};
The login component should then access the passed route state and redirect back to the original route being accessed.
const location = useLocation();
const navigate = useNavigate();
...
const login = () => {
...
const { from } = location.state || { from: { pathname: "/" } };
navigate(from, { replace: true });
};
You can achieve this by passing some params (next_route) for example. and keep it along the process in signin so that when he finishes he can ge reredirected to the right place (next_route)