I need to divide the browser router in two

Viewed 36

I'm working in a project where i need to divide the browser router in two, one for the public users and other for the admins, this is my idea:

<BrowserRouter>
  <Layout>
    <Route exact path="/" component="{Home}">
      <Switch>
        <Route exact path="/cart" component="{Cart}" />
        <Route exact path="/product/:productId" component="{ProductPage}" />
        <Route component="{NotFound}" />
      </Switch>
    </Route>
  </Layout>

  <AdminLayout>
    <Route exact path="/admin" component="{AdminHome}">
      <Switch>
        <Route exact path="/products" component="{AdminProductsList}" />
        <Route
          exact
          path="/product/:productId"
          component="{AdminEditProduct}"
        />
        <Route component="{NotFound}" />
      </Switch>
    </Route>
  </AdminLayout>
</BrowserRouter>

it clearly doesn't work this way but i would like to know which is the best way to make this work

UPDATE

now i've been working on it and i got to this

<BrowserRouter>
  <Switch>
    <Layout>
      <Route path="/">
        <Switch>
          <Route exact path="/" component="{Home}" />
          <Route exact path="/cart" component="{Cart}" />
          <Route exact path="/product/:productId" component="{ProductPage}" />
          <Route component="{NotFound}" />
        </Switch>
      </Route>
    </Layout>

    <AdminLayout>
      <Route path="/admin">
        <Switch>
          <Route exact path="/" component="{AdminHome}" />
          <Route exact path="/products" component="{AdminProductsList}" />
          <Route
            exact
            path="/product/:productId"
            component="{AdminEditProduct}"
          />
          <Route component="{NotFound}" />
        </Switch>
      </Route>
    </AdminLayout>
  </Switch>
</BrowserRouter>

the public("/") route works just fine but the admin("/admin") throws me a 404

2 Answers

you can have two array objects for two rules (admin and user), and then you can map it to Route components , like:

adminRoutes = [{path: '/admin', component: AdminHome, ...}]
nomralUserRoutes = [{path: '/', component: UserHome, isExact: true, ...}]
routes = isAdmin ? adminRoutes : nomralUserRoutes
render(){
  return (
<BrowserRouter>
    <Switch>
  routes.map(route => (<Route exact path={route.path} component={route.component} ... />))
    </Switch>
</BrowserRouter>)
}

Its just an example and you can make the route objects more complex to support more functionalities like Auth and ...

One of the ways I solve this problem is with a PrivateRoute HOC. You can modify this to your authentication needs.

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';

const PrivateRoute = ({ component: Component, auth, ...rest }) => (
  <Route
    {...rest}
    render={(props) =>
      auth.isAuthenticated === true ? <Component {...props} /> : <Redirect to="/login" />
    }
  />
);
PrivateRoute.propTypes = {
  auth: PropTypes.object.isRequired,
  component: PropTypes.elementType.isRequired,
};
const mapStateToProps = (state) => ({
  auth: state.auth,
});
export default connect(mapStateToProps)(PrivateRoute);

Then use this HOC wherever you want a route that is protected.

<PrivateRoute exact path="/products" component={AdminProductsList} />
<PrivateRoute exact path="/product/:productId" component={AdminEditProduct} />
Related