I'm a bit new to two-sided applications (and to React). I'm currently building an application that has both a "user" and a "business" side, and the type of user is decided after the user authenticates themselves. For that, my current approach is to simply create multiple versions of routers, and depending on the redux state for the user's type, I am dynamically loading in a different router. In the case that a user isn't authenticated, I am making use of a "generic" default router. Once the user logs in, the router is then switched to the appropriate one under App.js
I am wondering if there is a better way to do this, particularly because after a user authenticates themselves, there is a significant delay (a couple of seconds) in the router being switched in the background. For example, the route "/" goes to the landing page react component for the "generic" router, but goes to the dashboard page for the "user" router. Once the user logs in, I redirect them to the "/" router to move them to the dashboard page, however there is a weird delay and the user is actually taken back to the landing page for a few seconds, then the page re-builds to the proper user dashboard that is expected at the "/" route for an authenticated user.
Here is the code for the different types of routers:
export function UserRouter() {
return useRoutes([
{
path: '/learn',
element: <DashboardLayout />,
children: [
{ path: ':id', element: <Learn />},
]
},
{
path: '/dashboard',
element: <DashboardLayout />,
children: [
{ path: 'overview', element: <Overview /> },
{ path: 'tasks', element: <Tasks /> },
{ path: 'community', element: <Community /> },
{ path: 'announcements', element: <Announcements /> },
],
},
{ path: '/companies',
element: <DashboardLayout />,
children: [
{ path: ':id', element: <Company />},
]
},
{
path: '/termDocuments',
element: <EmptyPage />,
children: [
{ path: ':embedURL', element: <AirtableEmbedPage />},
]
},
{
path: '/',
element: <LogoOnlyLayout />,
children: [
{ path: '/', element: <Navigate to="/dashboard/overview" /> },
{ path: 'login', element: <Login /> },
{ path: 'register', element: <UserRegister /> },
{ path: 'landing', element: <Landing />},
{ path: '404', element: <NotFound /> },
{ path: '*', element: <Navigate to="/404" /> },
],
},
{ path: '*', element: <Navigate to="/404" replace /> },
]);
}
export function BusinessRouter() {
return useRoutes([
{
path: '/dashboard',
element: <DashboardLayout />,
children: [
{ path: 'overview', element: <BusinessOverview /> },
{ path: 'home', element: <BusinessHomePage /> },
{ path: 'community', element: <BusinessCommunity /> },
{ path: 'announcements', element: <BusinessAnnouncements /> },
],
},
{ path: '/companies',
element: <DashboardLayout />,
children: [
{ path: ':id', element: <Company />},
]
},
{
path: '/termDocuments',
element: <EmptyPage />,
children: [
{ path: ':embedURL', element: <AirtableEmbedPage />},
]
},
{
path: '/',
element: <LogoOnlyLayout />,
children: [
{ path: '/', element: <Navigate to="/dashboard/overview" /> },
{ path: 'login', element: <BusinessLogin /> },
{ path: 'register', element: <UserRegister /> },
{ path: 'landing', element: <Landing />},
{ path: '404', element: <NotFound /> },
{ path: '*', element: <Navigate to="/404" /> },
],
},
{
path: '/business',
element: <DashboardLayout />,
children: [
{ path: 'app', element: <Overview />}
],
},
{ path: '*', element: <Navigate to="/404" replace /> },
]);
}
export function GenericRouter() {
return useRoutes([
{
path: '/',
element: <LogoOnlyLayout/>,
children: [
{path: '/', element: <Landing/>},
{path: '404', element: <NotFound/>},
{path: 'founder', element: <Founders/>},
{path: '*', element: <Navigate to="/"/>},
// {path: '*', element: <Navigate to="/404"/>},
],
},
{
path: '/business',
element: <LogoOnlyLayout/>,
children: [
{path: 'login', element: <BusinessLogin/>},
{path: 'register', element: <UserRegister/>},
],
},
{
path: '/user',
element: <LogoOnlyLayout/>,
children: [
{path: 'login', element: <Login/>},
{path: 'register', element: <UserRegister/>},
],
},
{path: '*', element: <Navigate to="/" replace/>},
// {path: '*', element: <Navigate to="/404" replace/>},
]);
}
And here is the actual switching of the router based off of a redux variable that is updated in the background (within App.js)
const selectRouter = (userType) => {
switch (userType) {
case USER:
return <UserRouter/>
case BUSINESS:
return <BusinessRouter/>
default:
return <GenericRouter/>
}
}
function RouterChoice() {
const userType = useSelector(state => state.auth?.userType)
return selectRouter(userType)
}
export default function App() {
return (
<StylesProvider injectFirst>
<ThemeProvider>
<ScrollToTop />
<BaseOptionChartStyle />
<RouterChoice />
</ThemeProvider>
</StylesProvider>
);
}