It is hard to find a tutorial on how to create a web dashboard from scratch to deployment. In this blog post, I will take you through on how to create a simple dashboard using React and deploy it live on Netlify (CI/CD flow).

Prerequisite:

  • New React app project. See how to create Your First React App
  • Template. Download from this link (Credit: Creative Tim)
  • Create a free account on Netlify (for CI - Continuous Integration / CD - Continuous Deployment flow)

Project Structure

Go into your project and ensure the directory structure looks like this:

.
├── node_modules
├── package.json
├── package-lock.json
├── public
├── README.md
├── src
└── yarn.lock

3 directories, 4 files

Go into the src directory and create a directory named components. Inside the components directory create the following 6 files:

.
├── Dashboard.js
├── Footer.js
├── Main.js
├── Navbar.js
├── Sidebar.js
└── UserProfile.js

0 directories, 6 files

Open the Dashboard.js file and create a React component template as shown below:

import React, { Component } from 'react'

class Dashboard extends Component {
  render() {
    return <div></div>
  }
}

export default Dashboard

Apply this template to all other files replacing the class identifier name with the corresponding file name. This also includes the src/App.js file.

Unzip the template compressed file and copy the assets directory within it to the src directory. By now, your project structure should look like this.

.
├── App.css
├── App.js
├── App.test.js
├── assets
├── components
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js

2 directories, 7 files

Linking Assets

Open your template index.html file and copy this lines to your project public/index.html

    <!--     Fonts and icons     -->
    <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700,200" rel="stylesheet" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css" />

Open your src/index.js file and  add these import lines

import './assets/css/bootstrap.min.css'
import './assets/css/light-bootstrap-dashboard.css'
import './assets/css/dashboard.css'

Note:

  • Inside src/assets/css directory, rename the file demo.css to dashboard.css
  • I observed a bug in light-bootstrap-dashboard.css file. Find .navbar.fixed css identifier and comment as below:
.navbar.fixed {
    /* width: calc(100% - $sidebar-width); */
    right: 0;
    left: auto;
    border-radius: 0;
}

Install dependencies

Since our dashboard will have routes and charts, install the following dependencies:

npm i react-router-dom --save
npm i chartist --save
npm i react-chartist --save

Writing code

Starting with App.js file, update your code:

import React, { Component } from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Sidebar from './components/Sidebar'
import Main from './components/Main'

class App extends Component {
  render() {
    return (
      <div className="wrapper">
        <Router>
          <Sidebar />
          <Route path='/' component={Main} />
        </Router>
      </div>
    )
  }
}

export default App

Here we are including BrowserRouter as Router from react-router-dom to help us with navigating through our app. On app load, we render Sidebar and Main components. Note how Main component is included as a Route to be accessed by the root url.

On Sidebar.js, add the navigation links from the Template. Note: When copying the html outline from the template, remember to change html class attribute to className prop in your react project. This is because React uses JSX instead of HTML syntax for rendering elements to the DOM.

import React, { Component } from 'react'
import { NavLink, Link } from 'react-router-dom'

class Sidebar extends Component {
  render() {
    return (
      <div className="sidebar">
        <div className="sidebar-wrapper">
          <div className="logo">
            <Link to='/' className="simple-text">
              Simple Dashboard
            </Link>
          </div>
          <ul className="nav">
            <li className="nav-item">
              <NavLink className="nav-link" to='/dashboard'>
                <i className="nc-icon nc-chart-pie-35"></i>
                <p>Dashboard</p>
              </NavLink>
            </li>
            <li className="nav-item">
              <NavLink className="nav-link" to='/profile'>
                <i className="nc-icon nc-circle-09"></i>
                <p>User Profile</p>
              </NavLink>
            </li>

          </ul>
        </div>
      </div>
    )
  }
}

export default Sidebar

 For Main.js update your code to:

import React, { Component } from 'react'
import Navbar from './Navbar'
import Footer from './Footer'
import { Switch, Route, Redirect } from 'react-router-dom'
import Dashboard from './Dashboard'
import UserProfile from './UserProfile'

class Main extends Component {
  render() {
    return (
      <div className="main-panel">
        <Navbar />
        <Switch>
          <Route path="/dashboard" component={Dashboard} />
          <Route path="/profile" component={UserProfile} />
          <Redirect from='*' to='/dashboard' />
        </Switch>
        <Footer />
      </div>
    )
  }
}

export default Main

Notice here, we are using <Switch></Switch> to render one component at a time based on the active route.

The Navbar.js file will contain:

import React, { Component } from 'react'
import { Link } from 'react-router-dom'

class Navbar extends Component {
  render() {
    return (
      <nav className="navbar navbar-expand-lg " color-on-scroll="500">
        <div className="container-fluid">
          <a className="navbar-brand" href="/">Dashboard</a>
          <div className="collapse navbar-collapse justify-content-end" id="navigation">
            <ul className="navbar-nav ml-auto">
              <li className="nav-item">
                <Link className="nav-link" to='/'>
                  <span className="no-icon">Log out</span>
                </Link>
              </li>
            </ul>
          </div>
        </div>
      </nav>
    )
  }
}

export default Navbar

And the Footer.js will contain:

import React, { Component } from 'react'
import { Link } from 'react-router-dom'

class Footer extends Component {
  render() {
    return (
      <footer className="footer">
        <div className="container-fluid">
          <nav>
            <ul className="footer-menu">
              <li>
                <Link to="/">
                  Home
                </Link>
              </li>

            </ul>
            <p className="copyright text-center">
              © 2019
          </p>
          </nav>
        </div>
      </footer>
    )
  }
}

export default Footer

For Dashboard.js, we will import ChartistGraph from react-chartist package to help us render a pie chart and line graph.

import React, { Component } from 'react'
import ChartistGraph from 'react-chartist'

class Dashboard extends Component {
  render() {
    let dataPie = {
      labels: ["40%", "20%", "40%"],
      series: [40, 20, 40]
    }
    let dataSales = {
      labels: [
        "9:00AM",
        "12:00AM",
        "3:00PM",
        "6:00PM",
        "9:00PM",
        "12:00PM",
        "3:00AM",
        "6:00AM"
      ],
      series: [
        [287, 385, 490, 492, 554, 586, 698, 695],
        [67, 152, 143, 240, 287, 335, 435, 437],
        [23, 113, 67, 108, 190, 239, 307, 308]
      ]
    }
    return (
      <div className="content">
        <div className="container-fluid">
          <div className="row">

            <div className="col-md-4">
              <div className="card ">
                <div className="card-header ">
                  <h4 className="card-title">Email Statistics</h4>
                  <p className="card-category">Last Campaign Performance</p>
                </div>
                <div className="card-body ">
                  <ChartistGraph data={dataPie} type="Pie" />
                  <div className="legend">
                    <i className="fa fa-circle text-info"></i> Open
                                        <i className="fa fa-circle text-danger"></i> Bounce
                                        <i className="fa fa-circle text-warning"></i> Unsubscribe
                                    </div>
                  <hr />
                  <div className="stats">
                    <i className="fa fa-clock-o"></i> Campaign sent 2 days ago
                                    </div>
                </div>
              </div>
            </div>
            <div className="col-md-8">
              <div className="card">
                <div className="card-header ">
                  <h4 className="card-title">Users Behavior</h4>
                  <p className="card-category">24 Hours performance</p>
                </div>
                <div className="card-body ">
                  <ChartistGraph data={dataSales} type="Line" />
                </div>
                <div className="card-footer ">
                  <div className="legend">
                    <i className="fa fa-circle text-info"></i> Open
                    <i className="fa fa-circle text-danger"></i> Click
                    <i className="fa fa-circle text-warning"></i> Click Second Time
                </div>
                  <hr />
                  <div className="stats">
                    <i className="fa fa-history"></i> Updated 3 minutes ago
                  </div>
                </div>
              </div>
            </div>

          </div>
        </div>
      </div>
    )
  }
}

export default Dashboard

Finally, UserProfile.js will contain:

import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import face3 from "../assets/img/faces/face-3.jpg"

class UserProfile extends Component {
  render() {
    return (
      <div className="content">
        <div className="container-fluid">
          <div className="row">
            <div className="col-md-4">
              <div className="card card-user">
                <div className="card-image">
                  <img src="https://ununsplash.imgix.net/photo-1431578500526-4d9613015464?fit=crop&fm=jpg&h=300&q=75&w=400" alt="..." />
                </div>
                <div className="card-body">
                  <div className="author">
                    <Link to='/'>
                      <img className="avatar border-gray" src={face3} alt="..." />
                      <h5 className="title">Mike Andrew</h5>
                    </Link>
                    <p className="description">
                      michael24
                    </p>
                  </div>
                  <p className="description text-center">
                    "Lamborghini Mercy
                      <br /> Your chick she so thirsty
                      <br /> I'm in that two seat Lambo"
                  </p>
                </div>
                <hr />
                <div className="button-container mr-auto ml-auto">
                  <button className="btn btn-simple btn-link btn-icon">
                    <i className="fa fa-facebook-square"></i>
                  </button>
                  <button className="btn btn-simple btn-link btn-icon">
                    <i className="fa fa-twitter"></i>
                  </button>
                  <button className="btn btn-simple btn-link btn-icon">
                    <i className="fa fa-google-plus-square"></i>
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

export default UserProfile

That's it!

Deploy to live

First confirm if your project is running well by executing npm start. You can access it on http://localhost:3000/

If all is good, let us deploy to github.

  1. Create a new github repository https://github.com/new
  2. Link and push your project to the remote github repository created above:
git init
git remote add origin <your-github-repo-https-link>
git add --all
git commit -m "Initial commit"
git push origin master

3.  Login to netlify.com and click New site from Git. Follow the three step approach and your site will be deployed to Live!

Congratulations! 🎉 You now have a live simple react dashboard. You can share with your friends.

Here is a link to my live site: https://pensive-wozniak-88f792.netlify.com/

If you have questions or a suggestion, please share with me on the comment section.

Cheers!