Building the Require Admin HOC
Hey there, and welcome back to the course. In this video what we're going to do is basically take this admin and build a component around it, so we can require some components to have the admin ability.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

You have to be an admin to view that component, it won't render unless you're an admin, so let's go into our components, and let's create a new component and let's call it, well let's put it into our authentication.

Let's go to auth and create a new component, and we'll call it requireAdmin.js. OK now let's go down to require and let's rename this requireAdmin.js with a lowercase r. So requireAdmin with a lowercase r. Let's go down to require authentication to requireAuth.js let's copy this and let's go to requireAdmin and paste it.

Now we're not really going to write it like this, I just don't want to type out the connect and all that, so we're just going to have to refactor this and we're getting something from auth so it will be easier to explain. Okay so let's get rid of componentWillMount and WillUpdate. Let's rename the class to RequireAdmin and then what we're going to want to do is not use this history, we don't want that.

And then we don't want export default function, we don't want this to be a function. And then let's tab this all to the left and now let's get rid of this return and instead say RequireAdmin is equal to connect, and then the next thing we're going to want to do is not return composed component, let's get rid of that and now let's talk a bit.

requireAdmin.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

class RequireAdmin extends Component {
    render() {

    }
}

function mapStateToProps(state) {
    const { authenticated } = state.auth;
    return { authenticated }
}

RequireAdmin = connect(mapStateToProps)(Authentication);

So we have this class and what we want to do is we want to render a component only if they are authenticated and they are an admin. So what we'll do is we'll say mapStateToProps and instead of grabbing authenticated, right, so instead of grabbing authenticated we'll go in the user object and grab admin.

Okay, so let's rename this to admin, and let's say state.auth.user to grab it out of the user object. Now what we're going to want to do is go into our render function and say if this.props.admin then return. Then in braces here, or bracket's or whatever you want to call those curly braces, ...this.props.children.

So we're going to return the components that are wrapped with this component if admin is set to true and if not we're just going to return a div an empty div that doesn't do anything. Okay so there's nothing in there, so that should work.

Let's go ahead and let's try this out, after exporting it, so let's say export default RequireAdmin; and that should set us up. Okay so we have class admin extends Component, render and we have to return this so we're returning that.

requireAdmin.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

class RequireAdmin extends Component {
    render() {
        if(this.props.admin) {
            return {...this.props.children}
        }
        return <div></div>
    }
}

function mapStateToProps(state) {
    const { admin } = state.auth.user;
    return { admin }
}

RequireAdmin = connect(mapStateToProps)(Authentication);

export default RequireAdmin;

Okay so we should be good to go, let's go ahead and try it, some of these things are grayed out for some reason. I'm not sure why but we will see if it works anyway, and it should work. So what we're going to do want to do is we're going to want to go into newsletterGrid.js and let's import it into here, so say import RequireAdmin from '../auth/requireAdmin';.

And what we're going to want to do is basically just wrap this button this plus button right? So preview the page here, and get an error that says authentication is not defined. Let's go back to our RequireAdmin.js and the reason being is because we're trying to connect it to and authentication component but it's called RequireAdmin, so change that.

requireAdmin.js

function mapStateToProps(state) {
    const { admin } = state.auth.user;
    return { admin }
}

RequireAdmin = connect(mapStateToProps)(RequireAdmin);

export default RequireAdmin;

Okay, that should fix it. Let's come back and it's working. Okay so we want to do is we want to hide this plus button if the person is an admin, or if we have an admin account. So let's go back to newsletterGrid.js and let's take this button, command + x let's type out RequireAdmin and let's paste it in there.

newsletterGrid.js

<RequireAdmin>
    <Button className='newsletter-grid__button' icon='fas fa-plus' callback={() => this.handleAddNewsletter()}/>
</RequireAdmin>

So it's only going to render if this component within here, if it has Admin set true. So if we go in here and login with a normal account we won't see this plus button anymore.

large

Now if we go back and we sign in with John Cena or whatever account you made in the last video, you'll see that the button is here and we have access to a new newsletter.

large

So really awesome kind of stuff, let's go ahead and commit our code and in the next video we'll finish off every single last one that we need to handle with this functionality. The reason we don't in this video is just because we are building out the component, this whole RequireAdmin component.

Terminal

git status 
git add .
git commit -m "built require admin component and used it on the new newsletter button"
git push origin master

Resources

Source code