Building an Online Retail Dashboard in React

  • 2019-02-08 02:19 AM
  • 242

In this tutorial, we’ll be focusing on creating a dashboard for an Online Retail Store. Online Retail Stores generate revenue across other e-commerce giants, apart from their own website.

This dashboard focuses on showcasing a monthly performance of an online store across three e-commerce aggregators - Amazon, Ebay and Etsy. Further, we have used a combination of Charts, Maps, and KPI elements to showcase how different sources of revenue are performing, and from which geo locations are maximum orders are coming in from. Hope you have as much fun building this dashboard, as I did!

Table of Contents

Before we go ahead setting up, I wanted to show you a preview of the Online Retail Dashboard you’ll be able to create, once you’ve gone through this tutorial. Here’s a live link to dashboard in action.

Building an Online Retail Dashboard in React

Setting up the Environment

Including Dependencies We’ll be using the following dependencies for this project. To create the dashboard, you’ll need to set-up these dependencies as explained below:

  1. React, Bootstrap
  2. FusionCharts Core Package, its React Component and FusionMaps package

Including React We’ll be using Facebook’s React boilerplate today, which will set-up React along with all the utilities that we need. So, in your terminal, go ahead and enter:

$ npx create-react-app ecommerce-dashboard

To know more about create-react-app, please refer to this link. Now, we will be adding a few more components that we will need for this tutorial, as explained below:

Including Bootstrap We will be using Bootstrap to create the layout and user-interface for our app. So, in the terminal go ahead and enter:

$ npm install --save bootstrap

Including FusionCharts core package, it’s React Component and FusionMaps package We will be using FusionCharts to render charts in our dashboard app. You can go ahead and check out more about it here.

There are multiple ways to install FusionCharts, for general instructions you can check out this documentation page.

FusionCharts Direct Download You can directly download JS files from FusionCharts website using this link and include them in your application using <script> tag in /public/index.html of application.

Using NPM (we will be using this!) So, in the terminal, navigate to our working directory i.e. ecommerce-dashboard and enter:

$ npm install --save fusioncharts

To render maps, we will need also FusionMaps definition files. There are multiple ways to install them, for more details you can check out this developer documentation page.

Direct Download You can directly download JS files for all the maps from FusionCharts website using this link and include the respective map file which you want to render using <script> tag in /public/index.html of application.

Using NPM (we will be using this!) So, in the terminal, navigate to our working directory i.e. ecommerce-dashboard and enter:

$ npm install --save fusionmaps

FusionCharts also provides a lightweight and simple-to-use component for React that can be used to add JS charts in react app without any hassle. We will be using it in our app. Let’s install it using the command below:

$ npm install --save react-fusioncharts

You can learn more about FusionCharts react component using this link. Now that we have included all the dependencies, we will go ahead and set-up Google Sheets API.

Google Sheets API Setup We’ll start by creating a new project for our application on developer console to fetch data from Google Sheets. For this article, I’m naming it ecommerce-dashboard.

You can create a new project through this link.

Once the project is created, you’ll be redirected to Google Developer API dashboard. Now, we will enable Google Sheets API for our app. For this in the APIs box, click “Go to APIs overview”. Once you click “Enable APIs and Services” you’ll be presented with the API Library and we’ll go ahead and search for “Google Sheets API”.

Once you find it, click “Enable” and after it is processed you should be seeing the page below.

Building an Online Retail Dashboard in React

In the sidebar, head over to “Credentials” and click the “Create credentials” button and select “API Key”. Click the “Restrict Key” and set a name for it (I’ve named it as EcommerceDashboardAPIKey).

Save the key generated, as we’ll need it to pull data from our Google Sheet later.

Under “API Restrictions” select the “Google Sheets API” and save. Now, we are good to go for our next step where we’ll connect Google Sheets API and fetch the data.

Connecting Google Sheets and Fetching data

Now, let’s head to the Google Sheet that we will be using for this application. Here’s a screenshot of how it looks. I’ve collected random data for 13 months focusing on KPIs of for online retail business.

Building an Online Retail Dashboard in React

Now, we will make the sheet public so that anyone can see it. For this in the File menu, click “Share”. Once you click “Get shareable link” and after it’s processed, the sheet will be shared for “Anyone with link can view” access by default.

Since we want to make the sheet public, head over to “Anyone with link can view” and click the “More” option in the drop-down. Select “On - Public on the web” option and save.

You can access the sheet I’ll be using from this link. We’ll keep a note of the spreadsheet ID (this can be found in the URL for Google Sheets, for me its 1sCgmzBIq2K9jUckLuYSWbDq4CuNUfdtuE6a5xI3I5Hw).

We will be using batchGet method for our dashboard app. It returns one or more ranges of values from a spreadsheet. You can learn more about it here.

Let’s open up our working directory (ecommerce-dashboard for me) in a code editor and create a new file with name config.js. Input your API key and spreadsheet ID in it.

export default {
    apiKey: 'YOUR-API-KEY',
    spreadsheetId: '1sCgmzBIq2K9jUckLuYSWbDq4CuNUfdtuE6a5xI3I5Hw'
}

Now let’s head over to App.js file. We’ll be adding everything directly to App.js, which came with the boilerplate. This is not ideally the best architecture, rather just a display of the concepts.

Now let’s look at the steps below to show how I’ll connect our dashboard app to Google Sheets API and fetch data from it:

  1. Import config.js we created using the code below and declare a variable with request URL for Google Sheets API.
import config from './config';

const url = `https://sheets.googleapis.com/v4/spreadsheets/${ config.spreadsheetId }/values:batchGet?ranges=Sheet1&majorDimension=ROWS&key=${ config.apiKey }`;
  1. Now, we’ll set an empty array in this.state as shown in the code below:
constructor() {
    super();
    this.state = {
     items:[]
    };
  }
  1. Fetch the JSON data from React’s lifecycle componentDidMount method:
componentDidMount() {
    fetch(url).then(response => response.json()).then(data => {
      let batchRowValues = data.valueRanges[0].values;

      const rows = [];
      for (let i = 1; i < batchRowValues.length; i++) {
        let rowObject = {};
        for (let j = 0; j < batchRowValues++[++i].length; j++) {
          rowObject[batchRowValues[0][j]] = batchRowValues[i][j];
        }
        rows.push(rowObject);
      }

      this.setState({ items: rows });
    });
}

Awesome! Now that we have established a connection with our Google Sheets, we will start building the layout for our dashboard.

Note: You can verify the connection by logging the items variable inside state.

Building the Dashboard Layout

We’ll be using Bootstrap to build the layout for our application. We have already installed it, now let’s import it in our application. Head over to index.js and import the Bootstrap’s CSS file:

import "bootstrap/dist/css/bootstrap.css";

Now let’s divide our application’s layout into 4 parts:

  1. Navigation Section
  2. KPI Section
  3. KPI and Mini Charts Section
  4. Charts Section

We will also over-write some of the default styles provided by Bootstrap using our own CSS that will be present in the file style.css which is included in index.js file.

Creating the Navigation Section To create this, we will consume nav component provided by Bootstrap. You can check it out here. Below is the HTML snippet for the same:

<Nav className="navbar navbar-expand-lg fixed-top is-white is-dark-text">
      <div className="navbar-brand h1 mb-0 text-large font-medium">
        Online Retail Dashboard
      </div>
      <div className="navbar-nav ml-auto">
        <div className="user-detail-section">
          <span className="pr-2">Hi, Sean</span>
          <span className="img-container">
          <-- add image uri here -->
          <img src="" className="rounded-circle" alt="user" />
        </span>
      </div>
  </div>
</Nav>

Since we have two navigation sections in our application we will repeat the process above and customize the second navigation section using CSS.

Now, that our navigation section is ready, we’ll create a container to house the next three sections of our application. Here’s the HTML snippet for the same:

<div className="container-fluid">
<!-- kpi section -->

<!-- kpi + mini charts section -->

<!-- charts section -->
</div>

You can learn more about Bootstrap containers here.

Creating the KPI Section To create this, we’ll use rows, columns and cards provided by Bootstrap to create the layout for our KPI section as shown in the image above. Below is the HTML snippet for the same:

<div className="row">
  <div className="col-lg-3 col-sm-6">
    <div className="card">
      <div className="card-heading">
        <div>
          Total Revenue
        </div>
      </div>
      <div className="card-value">
        <span>$</span>

      </div>
    </div>
  </div>
</div>

The above snippet will create one KPI card (for “Total Revenue”). Similarly, we will create cards for all 4 KPIs that we want to showcase. You can learn more about rows, columns and cards from Bootstrap’s documentation using this link.

Creating the KPI and Mini-Charts Section To create this, we’ll again use rows, columns and cards provided by Bootstrap as we did in the previous step to create the layout for our KPI section as shown in the image above. Below is the HTML snippet for the same:

<div className="row">
  <div className="col-md-4 col-lg-3">
    <!-- kpi layout as in previous step -->
  </div>
  <div className="col-md-8 col-lg-9">
    <div className="card">
      <div className="row">
        <!-- row to include all mini-charts -->
        <div className="col-sm-4">
          <div className="chart-container">
            <!-- chart will come here -->
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

The above snippet will add one KPI to the left and one mini-chart section inside the card to the right. Similarly, we will add other two mini-charts layout inside the card as shown in the dashboard snapshot at the beginning of the article.

Creating the Mini-Charts Section To create this, we’ll again use rows, columns and cards provided by Bootstrap as we did in previous steps to create the layout for our charts as shown in the dashboard snapshot at the beginning of the article. Below is the HTML snippet for the same:

<div className="row">
  <div className="col-md-6">
    <div className="card">
      <div className="chart-div"></div>
      <!-- chart will come here -->
    </div>
  </div>
</div>

The above snippet will add one card. We can repeat the above step to create another card. If you’ve followed the above steps till now you should have a similar layout as in the dashboard snapshot at the beginning of the article. If not - don’t worry I’ll be adding the link to Github repo for this dashboard at the end of this tutorial.

Creating KPI’s

Now that our layout is ready, we will define functionality for elements and feed data to them from Google Sheets. For this, we will define a function called getData in our component which will take the month as an argument to de-structure google sheets data present in the app’s state.

Now, we’ll loop through the data to calculate values as needed for KPIs. Below is the code to create the KPI for “Revenue from Amazon”.

getData = arg => {
    // google sheet data
    const arr = this.state.items;
    const arrLen = arr.length;

    // kpi's
    // amazon revenue
    let amRevenue = 0;

    for (let i = 0; i < arrLen; i++) {
        if (arg === arr[i]["month"]) {
          if (arr[i]["source"] === "AM") {
            amRevenue += parseInt(arr[i].revenue);
          } 
        }
    }

    // setting state
    this.setState({
        amRevenue: amRevenue
    });
};

Similarly, we will define variables for other KPIs and assign a value to them upon looping through the data using the above code snippet.

Once the value for KPI is calculated we will set its value in app’s state to consume it in the layout as needed. Below is an example to consume the value from the state.

<div className="row">
  <div className="col-lg-3 col-sm-6">
    <div className="card">
      <div className="card-heading">
        <div>
          Revenue from Amazon
        </div>
      </div>
      <div className="card-value">
        <span>$</span>
        {this.state.amRevenue}
      </div>
    </div>
  </div>
</div>

Creating Charts

Now that our KPI’s are ready, we will loop through data and prepare JSON arrays for our charts and use FusionCharts and its React component to render the charts.

For this, we will be using getData function that we created in the previous step.

Now, we will create a file called chart-theme.js to create a theme for charts that we will be using. This theme will have cosmetics options for all our charts so that we don’t have to define them each time we create one. Here’s how it looks like:

window.FusionCharts.register("theme", {
  name: "ecommerce",
  theme: {
    base: {
      chart: {
        bgAlpha: "0",
        canvasBgAlpha: "0",
        baseFont: "basefont-regular",
        baseFontSize: "14",
        baseFontBold: "0",
        chartBottomMargin: "0",
        chartTopMargin: "0",
        chartLeftMargin: "0",
        chartRightMargin: "0",
        canvasBottomMargin: "0",
        canvasTopMargin: "0",
        canvasRightMargin: "0",
        canvasLeftMargin: "0",
        showBorder: "0",
        showCanvasBorder: "0",
        baseFontColor: "#ffffff",
        captionFontBold: "0",
        captionFontSize: "14",
        subCaptionFontSize: "14",
        tooltipColor: "#ffffff",
        tooltipBgColor: "#000000",
        tooltipBgAlpha: "60",
        tooltipPadding: "5",
        toolTipBorderAlpha: "10",
        toolTipBorderRadius: "3",
        showValues: "0",
        legendBgAlpha: "0",
        legendBorderAlpha: "0",
        legendBorderThickness: "0"
      }
    },
    bar2d: {
      chart: {
        placeValuesInside: "0",
        usePlotGradientColor: "0",
        showAlternateVGridColor: "0",
        chartLeftMargin: "5",
        canvasLeftMargin: "5",
        divLineAlpha: "10",
        divLineColor: "#ffffff",
        captionFontColor: "#8091ab",
        paletteColors: "#1D91C0",
        valuePadding: "5",
        yAxisName: "Orders",
        yAxisNameAlpha: "50",
        yAxisNameFontSize: "12",
        yAxisNamePadding: "20",
        valueFontBold: "0",
        valueFontSize: "12",
        plotToolText: "<div>$label<br><b>$value orders</b>",
        captionAlignment: "left",
        captionPadding: "20"
      }
    },
    doughnut2d: {
      chart: {
        captionFontSize: "14",
        captionFontColor: "#8091ab",
        showLabels: "0",
        showValues: "0",
        use3DLighting: "0",
        showPlotBorder: "0",
        defaultCenterLabel: "75%",
        pieRadius: "45",
        doughnutRadius: "33",
        showTooltip: "0",
        enableRotation: "0",
        enableSlicing: "0",
        startingAngle: "90"
      }
    },
    geo: {
      chart: {
        captionFontSize: "14",
        captionFontColor: "#8091ab",
        legendScaleLineThickness: "0",
        legendaxisborderalpha: "0",
        legendShadow: "0",
        plotFillAlpha: "85",
        showBorder: "1",
        borderColor: "#ffffff",
        borderThickness: "0.3",
        nullEntityColor: "#17202e",
        nullEntityAlpha: "50",
        entityFillHoverColor: "#17202e",
        captionAlignment: "left",
        entityToolText: "<div>$lname<br><b>$value orders</b>",
        chartLeftMargin: "40"
      }
    }
  }
});

You can learn more about FusionCharts themes from this documentation page.

Now let’s begin with creating mini-charts. We will be using Doughnut Chart (doughtnut2d) for this. You can learn more about this chart here.

getData = arg => {
  // google sheets data
  const arr = this.state.items;
  const arrLen = arr.length;
  let purchaseRate = 0;
  for (let i = 0; i < arrLen; i++) {
    if (arg === arr[i]["month"]) {
      purchaseRate += parseInt(arr[i].purchase_rate / 3);
    }
  }
  // setting state
  this.setState({
    purchaseRate: purchaseRate
  });
};

Now that our mini-chart’s value is set in the state we will initiate chart instance via FusionCharts’ React component and form JSON array to render the chart. Below is code for the same:

<div className="chart-container full-height">
    <ReactFC
      {...{
        type: "doughnut2d",
        width: "100%",
        height: "100%",
        dataFormat: "json",
        dataSource: {
          chart: {
            caption: "Purchase Rate",
            theme: "ecommerce",
            defaultCenterLabel: `${this.state.purchaseRate}%`,
            paletteColors: "#3B70C4, #000000"
          },
          data: [
            {
              label: "active",
              value: `${this.state.purchaseRate}`
            },
            {
              label: "inactive",
              alpha: 5,
              value: `${100 - this.state.purchaseRate}`
            }
          ]
        }
      }}
    />
</div>

This will create a mini-chart for “Purchase Rate”. Similarly, we can follow the above steps to create the other two mini-charts.

Now, let’s move to our charts section.

For this, we will define an empty array inside getData function and push data to it, after looping through Google Sheets data. Below is code snippet for the same:

getData = arg => {
  // google sheets data
  const arr = this.state.items;
  const arrLen = arr.length;

  // order trend by brand
  let ordersTrendStore = [];

  for (let i = 0; i < arrLen; i++) {
    if (arg === arr[i]["month"]) {
      if (arr[i]["source"] === "AM") {
        ordersTrendStore.push({
          label: "Amazon",
          value: arr[i].orders,
          displayValue: `${arr[i].orders} orders`
        });
      } else if (arr[i]["source"] === "EB") {
        ordersTrendStore.push({
          label: "Ebay",
          value: arr[i].orders,
          displayValue: `${arr[i].orders} orders`
        });
      } else if (arr[i]["source"] === "ET") {
        ordersTrendStore.push({
          label: "Etsy",
          value: arr[i].orders,
          displayValue: `${arr[i].orders} orders`
        });
      }
    }
  }

  // setting state
  this.setState({
    ordersTrendStore: ordersTrendStore
  });
};

Now that our chart’s data array is ready, we will initiate the charts instance via FusionCharts’ React component and form JSON array to render the chart.

<div className="chart-container">
    <ReactFC
      {...{
        type: "bar2d",
        width: "100%",
        height: "100%",
        dataFormat: "json",
        dataSource: {
          chart: {
            theme: "ecommerce",
            caption: "Orders Trend",
            subCaption: "By Stores"
          },
          data: this.state.ordersTrendStore
        }
      }}
    />
</div>

This will create Bar Chart (bar2d) chart in our application. You can learn more about this chart here.

Now that our first chart is ready, we will create our last chart which is a USA region map. For this, we have to import respective map definition file from FusionMaps package that we installed earlier. Below is code for the same:

import Maps from "fusioncharts/fusioncharts.maps";
import USARegion from "fusionmaps/maps/es/fusioncharts.usaregion";

To render the map, we will again define an empty array inside getData function and push data to it corresponding to respective ID which can be taken from this map specification sheet, after looping through Google Sheets data. Below is code snippet for the same:

getData = arg => {
  // google sheets data
  const arr = this.state.items;
  const arrLen = arr.length;

  // order trend by region
  let ordersTrendRegion = [];
  let orderesTrendnw = 0;
  let orderesTrendsw = 0;
  let orderesTrendc = 0;
  let orderesTrendne = 0;
  let orderesTrendse = 0;
  for (let i = 0; i < arrLen; i++) {
      orderesTrendnw += parseInt(arr[i].orders_nw);
      orderesTrendsw += parseInt(arr[i].orders_sw);
      orderesTrendc += parseInt(arr[i].orders_c);
      orderesTrendne += parseInt(arr[i].orders_ne);
      orderesTrendse += parseInt(arr[i].orders_se);
    }
  ordersTrendRegion.push({
    id: "01",
    value: orderesTrendne
  }, {
    id: "02",
    value: orderesTrendnw
  },{
    id: "03",
    value: orderesTrendse
  }, {
    id: "04",
    value: orderesTrendsw
  }, {
    id: "05",
    value: orderesTrendc
  });

  // setting state
  this.setState({
    ordersTrendRegion: ordersTrendRegion
  });
};

Now that our map’s data array is ready, we will initiate the charts instance via FusionCharts’ React component and form JSON array to render the map.

<div className="chart-container">
    <ReactFC
      {...{
        type: "usaregion",
        width: "100%",
        height: "100%",
        dataFormat: "json",
        dataSource: {
          chart: {
            theme: "ecommerce",
            caption: "Orders Trend",
            subCaption: "By Region"
          },
          colorrange: {
            code: "#F64F4B",
            minvalue: "0",
            gradient: "1",
            color: [
              {
                minValue: "10",
                maxvalue: "15",
                code: "#EDF8B1"
              },
              {
                minvalue: "15",
                maxvalue: "20",
                code: "#18D380"
              }
            ]
          },
          data: this.state.ordersTrendRegion
        }
      }}
    />
</div>

This will render our map. You can know more about maps and how to use them here.

We will now call getData function with Jan 2019 as an argument from componentDidMount method so that our dashboard loads with Jan 2019 data present in Google Sheet by default. If you’ve followed the above steps till now you should have a functional dashboard as in the image below:

Building an Online Retail Dashboard in React

I hope this tutorial will help you create this dashboard using Google Sheets! Now you can work your magic on adding more UI elements, charts, KPIs and more features.

I have added some styling and functionality myself and also used Styled Components for ease. You can know more about Styled Components here. And, you can check out the final live dashboard here.

For any references, you can check out the source code from this Github repository.

Learn More

Modern React with Redux

Become a JavaScript developer - Learn (React, Node,Angular)

The Complete React Web Developer Course (2nd Edition)

Node with React: Fullstack Web Development

Beginner Full Stack Web Development: HTML, CSS, React & Node

React JS and Redux - Mastering Web Apps

React 16 - The Complete Guide (incl. React Router 4 & Redux)

MERN Stack Front To Back: Full Stack React, Redux & Node.js

Original source: https://scotch.io

Suggest