Skip to content

Instantly share code, notes, and snippets.

@kcjpop
Created November 29, 2018 16:39
Show Gist options
  • Save kcjpop/d3324648222bdbec48d163ca4ddb4d3e to your computer and use it in GitHub Desktop.
Save kcjpop/d3324648222bdbec48d163ca4ddb4d3e to your computer and use it in GitHub Desktop.
// App.js
import * as Analytics from 'modules/analytics';
import * as Auth from 'modules/auth';
import * as Search from 'modules/search';
import * as Users from 'modules/users';

// HOC to check logged in user
function checkAuthentication(Component) {
  return class extends React.Component {
    state = {currentUser: null};

    componentDidMount() {
      api.isLoggedIn()
        .then(currentUser => this.setState({ currentUser }))
        .catch(() => this.setState({ currentUser: null }));
    }

    render() {
      if (this.state.currentUser === null) return <div>Loading...</div>;
      return this.state.currentUser ? (
        <Component />
      ) : (
        <Redirect noThrow to="/auth/login" />
      );
    }
  };
}

const PROTECTED_ROUTES = [
  ...Analytics.routes,
  ...Search.routes,
  ...Users.routes,
].map(({component, ...props}) => ({
  props,
  Component: checkAuthentication(component),
}));

export default function App(props) {
  return (
    <Router>
      {[...PUBLIC_ROUTES, ...PROTECTED_ROUTES].map(({Component, props}) => (
        <Component key={props.path} {...props} /> // eslint-disable-line
      ))}
      <Redirect noThrow from="/" to="/analytics" />
    </Router>
  );
}

Modules are structured like this:

src/modules
├── analytics
│   ├── components
│   │   ├── Chart.js
│   │   └── Main.js
│   ├── index.js
│   └── routes.js
├── auth
│   ├── components
│   │   └── Login.js
│   ├── index.js
│   └── routes.js
├── search
│   ├── actions.js
│   ├── components
│   │   ├── FilterDialog.js
│   │   ├── Main.js
│   │   ├── Map.js
│   │   ├── MediaItem.js
│   │   ├── MediaItemDialog.js
│   │   └── MediaSubscriber.js
│   ├── index.js
│   └── routes.js
└── users
    ├── components
    │   ├── Main.js
    │   └── UserSideSheet.js
    ├── index.js
    └── routes.js

An example routes.js

// src/modules/search/routes.js
import Main from './components/Main';

export default [
  {
    path: '/search',
    component: Main,
  },
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment