Skip to content

Commit

Permalink
solutions to react exercices of week 6
Browse files Browse the repository at this point in the history
  • Loading branch information
Systho committed Nov 9, 2018
1 parent b6b5cfc commit a5554fd
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 49 deletions.
33 changes: 20 additions & 13 deletions src/client/react/components/footer/footer.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import React from 'react';
import React from "react";

import Navbar from 'react-bootstrap/lib/Navbar';
import { withAuthentication } from "react/contexts/authentication.js";
import { Navbar, Nav, Button } from "react-bootstrap";
import { withAuthentication } from "react/contexts/authentication";
import { withTheme } from "react/contexts/theme";


const Navigation = ({ jwt }) => {
return (
<Navbar bg="dark" variant="dark" fixed="bottom" >
<Navbar.Brand>Current JWT : { jwt } </Navbar.Brand>

</Navbar>
);
}
const Navigation = ({ jwt, theme, toggleTheme }) => {
return (
<Navbar bg={theme} variant={theme} fixed="bottom">
<Nav className="mr-auto">
<Navbar.Brand>Current JWT : {jwt} </Navbar.Brand>
</Nav>
<Button variant="outline-info" onClick={toggleTheme}>
Change Theme
</Button>
</Navbar>
);
};

const NavigationWithAuthentication = withAuthentication(Navigation);
export default NavigationWithAuthentication;
const NavigationWithAuthenticationAndTheme = withTheme(
NavigationWithAuthentication
);
export default NavigationWithAuthenticationAndTheme;
9 changes: 5 additions & 4 deletions src/client/react/components/login/login_container.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { Redirect } from 'react-router-dom';

import {withAuthentication} from 'react/contexts/authentication';
import LoginComponent from './login_component';


Expand All @@ -11,8 +12,6 @@ class LoginContainer extends React.Component {
this.state = {
email: "",
password: "",
authenticated: false,
jwt: null,
};

this.authenticate = this.authenticate.bind(this);
Expand All @@ -26,8 +25,10 @@ class LoginContainer extends React.Component {
}

authenticate(e){
const { login } = this.props;
const { email, password } = this.props;
e.preventDefault();
// use login from injected context
login({email, password});
}


Expand Down Expand Up @@ -59,4 +60,4 @@ class LoginContainer extends React.Component {
}


export default LoginContainer;
export default withAuthentication(LoginContainer);
9 changes: 6 additions & 3 deletions src/client/react/components/main.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React from "react";
import { HashRouter } from "react-router-dom";

import {AuthenticationProvider} from "react/contexts/authentication";
import { AuthenticationProvider } from "react/contexts/authentication";
import { ThemeProvider } from "react/contexts/theme";
import Layout from "./layout";

function Main() {
return (
<HashRouter>
<AuthenticationProvider >
<Layout />
<AuthenticationProvider>
<ThemeProvider>
<Layout />
</ThemeProvider>
</AuthenticationProvider>
</HashRouter>
);
Expand Down
14 changes: 8 additions & 6 deletions src/client/react/components/navigation/navigation.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React from 'react';

import Navbar from 'react-bootstrap/lib/Navbar';
import Nav from 'react-bootstrap/lib/Nav';
import { Nav, Navbar, Button } from 'react-bootstrap';
import { Link } from 'react-router-dom';

import {withAuthentication} from 'react/contexts/authentication';
import {withTheme} from 'react/contexts/theme';
import SearchForm from './search_form';


const Navigation = () => {
const Navigation = ({ logout, theme }) => {
return (
<Navbar bg="dark" variant="dark">
<Navbar bg={ theme } variant={ theme }>
<Navbar.Brand as={Link} to="/">Navbar</Navbar.Brand>
<Nav className="mr-auto">
<Nav.Link as={Link} to="/" >Hello</Nav.Link>
Expand All @@ -17,9 +18,10 @@ const Navigation = () => {
<Nav.Link as={Link} to="/login" >Login</Nav.Link>
</Nav>
<SearchForm />
<Button variant="outline-warning" onClick={ logout }>Logout</Button>
</Navbar>
);
}


export default Navigation;
export default withTheme(withAuthentication(Navigation));
31 changes: 17 additions & 14 deletions src/client/react/components/router_outlet.jsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import React from "react";
import { Route, Redirect, withRouter } from "react-router-dom";

import { Route } from "react-router-dom";

import { withAuthentication } from "react/contexts/authentication";
import HelloWorld from "./hello_world/hello_world";
import HelloFromParams from "./hello_world/hello_from_params";
import TodoAppContainer from "./todo_app/todo_app_container";
import MessagesContainer from "./messages/messages_container";
import MessageContainer from "./message/message_container";
import LoginContainer from "./login/login_container";

function RouterOutlet() {
function RouterOutlet({ isAuthenticated, location: { pathname } }) {
const redirectToLogin = !isAuthenticated && pathname !== "/login";

return (
<React.Fragment>
<Route
exact
path="/"
render={() => <HelloWorld name="bob" />}
/>
<Route path="/hello/:name" component={HelloFromParams} />
<Route path="/todo" component={TodoAppContainer} />
<Route path="/messages" component={MessagesContainer} />
<Route path="/message/:id" component={MessageContainer} />
<Route path="/login" component={LoginContainer} />
{ redirectToLogin && <Redirect to="/login" /> }
{ !redirectToLogin &&
<React.Fragment>
<Route exact path="/" render={() => <HelloWorld name="bob" />} />
<Route path="/hello/:name" component={HelloFromParams} />
<Route path="/todo" component={TodoAppContainer} />
<Route path="/messages" component={MessagesContainer} />
<Route path="/message/:id" component={MessageContainer} />
<Route path="/login" component={LoginContainer} />
</React.Fragment>
}
</React.Fragment>
);
}

export default RouterOutlet;
export default withRouter(withAuthentication(RouterOutlet));
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as Session from 'react/services/session.js'

const AuthenticationContext = React.createContext({
jwt: null,
isAuthenticated: false,
login: () => {},
logout: () => {}
});
Expand All @@ -14,8 +15,12 @@ class AuthenticationProvider extends React.Component {
constructor(props) {
super(props);

const jwt = localStorage.getItem("JWT");
const isAuthenticated = !!jwt;

this.state = {
jwt: localStorage.getItem("JWT")
jwt,
isAuthenticated,
};

this.login = this.login.bind(this);
Expand All @@ -28,28 +33,29 @@ class AuthenticationProvider extends React.Component {
.then( jwt => {
this.setState({
jwt: jwt,
isAuthenticated: !!jwt,
})
})
}
logout() {
return Session
.deleteSession()
.then( () => {
this.setState({
Session.deleteSession();

this.setState({
jwt: null,
})
})
isAuthenticated: false,
});
}

render() {
const { login, logout } = this;
const { jwt } = this.state;
const { jwt, isAuthenticated } = this.state;
const { children } = this.props;

const providerValues = {
jwt,
isAuthenticated,
login,
logout
logout,
};
return (
<AuthenticationContext.Provider value={providerValues}>
Expand Down
66 changes: 66 additions & 0 deletions src/client/react/contexts/theme.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from "react";
import withContextConsumer from "react/utils/with_context_consumer.jsx";

const ThemeContext = React.createContext({
theme: "dark",
setThemeLight: () => {},
setThemeDark: () => {},
toggleTheme: () => {},
});

const ThemeConsumer = ThemeContext.Consumer;

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

this.state = {
theme: "dark"
};

this.setTheme = this.setTheme.bind(this);
this.toggleTheme = this.toggleTheme.bind(this);
}

setTheme(value) {
this.setState({
theme: value
});
}

toggleTheme() {
const { theme } = this.state;

switch(theme){
case "dark":
this.setTheme("light");
break;

default:
case "light":
this.setTheme("dark");
}
}

render() {
const { setTheme, toggleTheme } = this;
const { theme } = this.state;
const { children } = this.props;

const providerValues = {
theme,
setThemeDark: () => setTheme("dark") ,
setThemeLight: () => setTheme("light") ,
toggleTheme,
};
return (
<ThemeContext.Provider value={providerValues}>
{children}
</ThemeContext.Provider>
);
}
}

const withTheme = withContextConsumer(ThemeConsumer);

export { ThemeConsumer, ThemeProvider, withTheme };

0 comments on commit a5554fd

Please sign in to comment.