Skip to content
Merged
56 changes: 18 additions & 38 deletions client/routes.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Login from '../imports/ui/components/login.jsx';
import Landing from '../imports/ui/components/landing.jsx';
import Navbar from '../imports/ui/components/navbar.jsx';
Expand All @@ -8,48 +8,28 @@ import Woohoo from '../imports/ui/components/woohoo.jsx';
import Apply from '../imports/ui/components/apply.jsx';
import ForgotPassword from '../imports/ui/components/forgot_password.jsx';
import SetPassword from '../imports/ui/components/set_password.jsx';
import Profile from '../imports/ui/components/dashboard/profile.jsx';
import Moderator from '../imports/ui/components/moderator.jsx';
import withUser from '../imports/ui/components/hoc/with-user.jsx';
import Profile from '../imports/ui/components/dashboard/profile';
import AuthenticatedRoute from '../imports/ui/components/hoc/AuthenticatedRoute';
import { AuthProvider } from '../imports/ui/components/hoc/AuthProvider';

export const renderRoutes = () => (
<Router>
<Switch>
<AuthProvider>
<Navbar>
<Route exact path="/" component={Landing} />
<RouteWithUser exact path="/dashboard" component={Profile} />
<RouteWithOutUser exact path="/login" component={Login} />
<RouteWithOutUser exact path="/forgot-password" component={ForgotPassword} />
<RouteWithOutUser exact path="/enroll-account/:token" component={SetPassword} />
<RouteWithOutUser exact path="/reset-password/:token" component={SetPassword} />
<RouteWithUser exact path="/moderator" component={Moderator} />
<Route exact path="/faq" component={Faq} />
<RouteWithOutUser path="/apply" component={Apply} />
<Route path="/woohoo" component={withUser(Woohoo)} />
<Switch>
<AuthenticatedRoute path="/dashboard" component={Profile} />
<AuthenticatedRoute path="/moderator" component={Moderator} />
<Route path="/login" component={Login} />
<Route path="/forgot-password" component={ForgotPassword} />
<Route exact path="/enroll-account/:token" component={SetPassword} />
<Route exact path="/reset-password/:token" component={SetPassword} />
<Route exact path="/faq" component={Faq} />
<Route path="/apply" component={Apply} />
<Route path="/woohoo" component={Woohoo} />
<Route exact path="/" component={Landing} />
</Switch>
</Navbar>
</Switch>
</AuthProvider>
</Router>
);

// All routes where user supposed to be logged in
// If user is not logged in, redirect them to login page
const RouteWithUser = withUser(({ user, component: Component, ...rest }) => {
const { pathname } = window.location;

if (user) {
return <Route {...rest} render={props => <Component {...props} user={user} />} />;
} else if (pathname !== '/login' && pathname === rest.path) {
return <Redirect push to="/login" />;
}
return null;
});

const RouteWithOutUser = withUser(({ user, component: Component, ...rest }) => {
const { pathname } = window.location;
if (!user) {
return <Route {...rest} render={props => <Component {...props} user={user} />} />;
} else if (pathname !== '/dashboard' && pathname === rest.path) {
return <Redirect push to="/dashboard" />;
}
return null;
});
9 changes: 7 additions & 2 deletions imports/ui/components/forgot_password.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Link } from 'react-router-dom';
import { Alert, Container, Button, Form, Row, Col } from 'react-bootstrap';
import { Accounts } from 'meteor/accounts-base';
import { EMAIL_REGEX } from '/imports/constants/regex';
import { AuthContext } from './hoc/AuthProvider';
import { Redirect } from 'react-router-dom';

class ForgotPassword extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -36,8 +38,11 @@ class ForgotPassword extends React.Component {

render() {
const { validated, error, success, processing } = this.state;
const { user } = this.context;

return (
return user ? (
<Redirect to="/home" />
) : (
<Container fluid>
<Row>
<Col sm={{ span: 6, offset: 3 }} lg={{ span: 4, offset: 4 }}>
Expand Down Expand Up @@ -76,5 +81,5 @@ class ForgotPassword extends React.Component {
);
}
}

ForgotPassword.contextType = AuthContext;
export default ForgotPassword;
25 changes: 25 additions & 0 deletions imports/ui/components/hoc/AuthProvider.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
const AuthContext = React.createContext();

class AuthProvider extends React.Component {
constructor() {
super();
}
state = {
user: null,
};

componentDidMount() {
Accounts.onLogout(() => this.setState({ user: null }));
Accounts.onLogin(() => this.setState({ user: Meteor.user() }));
}

render() {
return <AuthContext.Provider value={{ user: this.state.user }}> {this.props.children} </AuthContext.Provider>;
}
}

const AuthConsumer = AuthContext.Consumer;
export { AuthProvider, AuthConsumer, AuthContext };
11 changes: 11 additions & 0 deletions imports/ui/components/hoc/AuthenticatedRoute.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { AuthConsumer } from './AuthProvider';

const AuthenticatedRoute = ({ component: Component, ...rest }) => (
<AuthConsumer>
{({ user }) => <Route render={props => (user ? <Component {...props} /> : <Redirect to="/login" />)} {...rest} />}
</AuthConsumer>
);

export default AuthenticatedRoute;
11 changes: 8 additions & 3 deletions imports/ui/components/landing.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Link, Redirect } from 'react-router-dom';
import { Container, Row, Col } from 'react-bootstrap';
import BoardContainer from '/imports/ui/containers/board.jsx';
import { AuthContext } from './hoc/AuthProvider';

class Landing extends React.Component {
constructor(props) {
super(props);
}

render() {
return (
const { user } = this.context;

return user ? (
<Redirect to="/dashboard" />
) : (
<Container>
<Row>
<Col className="h-100" style={{ marginTop: 140 }}>
Expand Down Expand Up @@ -65,5 +70,5 @@ class Landing extends React.Component {
);
}
}

Landing.contextType = AuthContext;
export default Landing;
11 changes: 7 additions & 4 deletions imports/ui/components/login.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Link, Redirect } from 'react-router-dom';
import { Alert, Container, Button, Form, Row, Col } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { EMAIL_REGEX } from '/imports/constants/regex';

import { AuthContext } from './hoc/AuthProvider';
class Login extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -33,8 +33,11 @@ class Login extends React.Component {

render() {
const { validated, error } = this.state;
const { user } = this.context;

return (
return user ? (
<Redirect to="/dashboard" />
) : (
<Container fluid>
<Row>
<Col sm={{ span: 6, offset: 3 }} lg={{ span: 4, offset: 4 }}>
Expand Down Expand Up @@ -77,5 +80,5 @@ class Login extends React.Component {
);
}
}

Login.contextType = AuthContext;
export default Login;
41 changes: 25 additions & 16 deletions imports/ui/components/moderator.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import React from 'react';
import { Container, Row, Col } from 'react-bootstrap';
import { AuthContext } from './hoc/AuthProvider';
import BoardContainer from '/imports/ui/containers/board.jsx';

const Moderator = props => {
const { user } = props;
const { name } = (user && user.profile) || {};
return (
<Container>
<Row>
<Col className="h-100" style={{ marginTop: 40 }}>
<hgroup className="mx-auto p-4 text-center">
<h3>Hello {name}! You are logged in!</h3>
</hgroup>
<BoardContainer />
</Col>
</Row>
</Container>
);
};
class Moderator extends React.Component {
constructor(props) {
super(props);
}

render() {
const { user } = this.context;
const { name } = (user && user.profile) || {};

return (
<Container>
<Row>
<Col className="h-100" style={{ marginTop: 40 }}>
<hgroup className="mx-auto p-4 text-center">
<h3>Hello {name}! You are logged in!</h3>
</hgroup>
<BoardContainer />
</Col>
</Row>
</Container>
);
}
}

Moderator.contextType = AuthContext;
export default Moderator;
9 changes: 5 additions & 4 deletions imports/ui/components/navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react';
import { Link } from 'react-router-dom';
import { Navbar, Nav, Button, Container } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import withUser from '/imports/ui/components/hoc/with-user.jsx';
import { AuthContext } from './hoc/AuthProvider';

class NavbarWrapper extends React.Component {
class NavigationBar extends React.Component {
constructor(props) {
super(props);
}
Expand All @@ -14,7 +14,7 @@ class NavbarWrapper extends React.Component {
}

render() {
const { user } = this.props;
const { user } = this.context;

return (
<React.Fragment>
Expand Down Expand Up @@ -61,4 +61,5 @@ class NavbarWrapper extends React.Component {
}
}

export default withUser(NavbarWrapper);
NavigationBar.contextType = AuthContext;
export default NavigationBar;