# Module 4: Getting Started with Workouts

In this module, we're going to set up the other side of the application. So far we've been working on login, signup, and logout. Now, we're going to work with what happens once the user is already logged in.

## Step 1. Splash Page <a href="#splash-mountain5" id="splash-mountain5"></a>

Let's start by creating some files and folders. Inside of your `home` folder, go ahead and create a new file called `Splash.js`. Inside of src, make a new folder called `workouts`. Inside of `workouts`, create a new file called `WorkoutIndex.js`. The two files we've just created are the parent components for the workout side of the applications.

Once you have done this, navigate inside of `Splash.js`, and type the following code if you save your code there will be an error:

```jsx
import React, { Component } from 'react';
import WorkoutIndex from '../workouts/WorkoutIndex';

const Splash = (props) => {
  return (
      <div>
          <WorkoutIndex/>
      </div>
  ) 
}

export default Splash;
```

The error is because we haven't added any code for the `WorkoutIndex.js` file, let's resolve that now:

```jsx
import React, { Component } from 'react';

class WorkoutIndex extends Component{

    render(){
        return (
            <div>
                Workout Index
            </div>
        )
    }
}

export default WorkoutIndex;
```

So, now we have stubbed out our two components that set up our workout side of the application.

## Back to App.js

So, the structure of our application basically has two different sides: 1) if they are not yet logged in/signed up 2) if they are.

Then 2 more sides to those:

1\) is the `<Auth />` component and children 2) is the `<Splash />` component and children.

We need to set up our `App.js` to handle routing and everything for these two different sides of our application. Let's first make sure we have everything we need imported, your total imports in this file should look like this:

```javascript
import React, { Component } from 'react';
import Auth from './auth/Auth';
import NavBar from './home/NavBar';
import Splash from './home/Splash';
import {
  BrowserRouter as Router,
  Route,
  Switch
} from 'react-router-dom'
```

We've got our Auth, Navbar, and Splash components, which is what we need to handle routing and rendering in our `App.js`.

Next, we need to take care of rendering the appropriate components based on whether or not the user is logged in (and remember to determine this we are checking for a sessionToken). Let's create a function that we can call in our render that takes care of this logic for us, so that we don't have that cluttering up our `render()`. Create the following function underneath your other functions already in `App.js` and above your `render`:

```javascript
  protectedViews = () => {
    if (this.state.sessionToken === localStorage.getItem('token')) {
      return (
        <Switch>
          <Route path='/' exact>
            <Splash sessionToken={this.state.sessionToken} />
          </Route>
        </Switch>
      )
    } else {
      return (
        <Route path="/auth" >
          <Auth setToken={this.setSessionState}/>
        </Route>
      )
    }
  }
```

Let's talk through the above function. Essentially all we are doing here is checking to see if there is a sessionToken in the state, and if it matches the token stored in localStorage. If it does, i.e. if the user is logged in, we're going to display the `<Splash />` component, we're also passing along our `sessionToken` as a prop to Splash so that side of the application can use it to make requests to the server. If the user is not logged in, we're going to direct them to the Auth side of the application so that they can get logged in, we can grab the token, and then they can use the workout side of the application.

Lastly, we need to call this function in our render. Change your `App.js` render to look like the following:

```javascript
render() {
    return (
      <Router>
        <div>
          <NavBar clickLogout={this.logout} />
          {this.protectedViews()}
        </div>
      </Router>

    );
  }
```

Notice how we are displaying our `<NavBar />` all the time regardless of whether or not the user is logged in. Everything else depends on whether or not they are logged in. It's nice to have this all in a function, so that when we add more complexity to our application our render can stay the same, and the new logic can be in the `protectedViews` function.

At this point, this is the code for the completed `App.js`.

```javascript
import React, { Component } from 'react';
import Auth from './auth/Auth';
import NavBar from './home/NavBar';
import Splash from './home/Splash';
import {
  BrowserRouter as Router,
  Route,
  Switch
} from 'react-router-dom';

class App extends Component {
  constructor() {
    super();
    this.state = {
      sessionToken: '',
    }
  }

  componentWillMount() {
    const token = localStorage.getItem('token')
    if (token && !this.state.sessionToken) {
      this.setState({ sessionToken: token });
    }
  }

  setSessionState = (token) => {
    localStorage.setItem('token', token);
    this.setState({ sessionToken: token });
  }

  logout = () => {
    this.setState({ sessionToken: ''});
    localStorage.clear();
  }


  protectedViews = () => {
    if (this.state.sessionToken === localStorage.getItem('token')) {
      return (
        <Switch>
          <Route path='/' exact>
            <Splash sessionToken={this.state.sessionToken} />
          </Route>
        </Switch>
      )
    } else {
      return (
        <Route path="/auth" >
          <Auth setToken={this.setSessionState}/>
        </Route>
      )
    }

  }

  render() {
    return (
      <Router>
        <div>
          <NavBar clickLogout={this.logout} />
          {this.protectedViews()}
        </div>
      </Router>

    );
  }
}

export default App;
```

Now, that in our `App.js` we passed our sessionToken to the `<Splash />` component we can pass that along to our WorkoutIndex inside of `Splash.js`. Change `Splash.js` render to look like this:

```javascript
import React from 'react';
import WorkoutIndex from '../workouts/WorkoutIndex';

const Splash = (props) => {
    return (
        <div>
            <WorkoutIndex token={props.sessionToken} />
        </div>
    )
}

export default Splash;
```

## Step 2. Workout Start <a href="#workout-index5" id="workout-index5"></a>

Next, let's start working on our main parent for the workout side of the application, `WorkoutIndex.js`.

First, import all of our components we just created, and react and reactstrap:

```jsx
import React from 'react';
import { Container, Row, Col } from 'reactstrap';
```

Next, we are going to do is build out our whole constructor. Type out the following code:

```jsx
constructor(props) {
    super(props)
    this.state = {
      workouts: []
    }
  }
```

Things to note about the constructor:

* we set up our state for the component, we have an array of workouts

Awesome. Now we are going to go ahead and build out a simple fetch workouts function:

```jsx
fetchWorkouts = () => {
    fetch("http://localhost:3000/api/log", {
        method: 'GET',
        headers: new Headers({
            'Content-Type': 'application/json',
            'Authorization': this.props.token
        })
    })
        .then((res) => res.json())
        .then((logData) => {
            return this.setState({ workouts: logData })
        })
}
```

What we are doing in `fetchWorkouts` is getting our workouts from our server. Note that we are including the `Authorization` header, and our token that was passed as a prop from above. Remember that we need our Authorization header so that the server can know who is making the requests, and understand them. Also notice that after we get back information from the server, we are saving the workout information to our state. Next, we need to actually call this function to run when our component mounts. Remember that `componentDidMount` is the best place for API calls because it is only called once.

```jsx
componentDidMount() {
    this.fetchWorkouts()
}
```

Then we update our render with things that are not built out yet, but set up so that we can use them:

```jsx
render() {
    return (
      <Container>
        <Row>
          <Col md="3">
            {/* the create component will go here*/}
          </Col>
          <Col md="9">
            <h2>Log a workout to see table this will be added in the upcoming modules</h2>
          </Col>
        </Row>
      </Container>
    )
  }
```

## Finished Code:

```javascript
import React from 'react';
import WorkoutCreate from './WorkoutCreate';
import { Container, Row, Col } from 'reactstrap';

class WorkoutIndex extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
      workouts: []
    }
  }

  componentWillMount() {
    this.fetchWorkouts()
  }

  fetchWorkouts = () => {
    fetch("http://localhost:3000/api/log", {
      method: 'GET',
      headers: new Headers({
        'Content-Type': 'application/json',
        'Authorization': this.props.token
      })
    })
      .then((res) => res.json())
      .then((logData) => {
        return this.setState({ workouts: logData })
      })
  }

  render() {
    return (
      <Container>
        <Row>
          <Col md="3">
            {/* the create component will go here*/}
          </Col>
          <Col md="9">
            <h2>Log a workout to see table this will be added in the upcoming modules</h2>
          </Col>
        </Row>
      </Container>
    )
  }
}

export default WorkoutIndex
```
