Skip to main content

Custom Dashboards Based On Panorama

About

In this tutorial, we will walk through creating a custom dashboard experience powered by Helium. We'll first identify which GraphQL calls we'll use to fetch the data necessary for the dashboard, then we'll build out the frontend components to populate the dashboard. Lastly, we'll add routing.

Our final dashboard will have a welcome message, information about the learners' courses, and badging information.

Part 1: API Calls

First we'll make a series of API calls to populate the new custom dashboard.

CurrentUser Query

We'll call the CurrentUser query to fetch the user's name, courses, and their panorama.

query {
CurrentUser {
firstName
lastName
client {
name // this represents the name of the Panorama the user belongs to
}
}
}

UserContentItems Query

We'll fetch the content that the user has access to with UserContentItems.

query {
UserContentItems {
title
id
}
}

UserRecentContent Query

We'll also fetch their most recent content items to display on the dashboard.

query {
UserRecentContent {
title
asset
}
}

UserCertificates Query

Finally, we'll call the UserCertificates query to fetch certificates data.

UserCertificates {
source
certificateTemplate {
title
}
}

Part 2: Building the Dashboard Frontend

Building a Custom Welcome Message

First, we'll create a custom welcome message. To start we'll just call the GraphQL API and log the result.

/components/Dashboard.tsx
import React, { useState, useEffect } from 'react';
import { gql, useQuery, useMutation } from '@apollo/client';

function Dashboard() {

const dashboard_query = gql`
query DashboardQuery {
CurrentUser {
firstName
client {
name
}
}
}`

const { data, error } = useQuery(course_query);

if (data) {
console.log(data)
}

return (
<div>
<h1>I'm a custom dashboard page!</h1>
<div>
)
}

export { Dashboard };

When that looks good, we'll add logic to render a welcome message.

/components/Dashboard.tsx
// note: this code is strictly for reference, these are dummy files and this code is unstyled
...
let header;
let backgroundImage;
if (data) {
if (data.CurrentUser.client.name == "New York") {
backgroundImage = <img src="newYorkPicture"/>
} else if (data.CurrentUser.client.name == "Los Angles") {
backgroundImage = <img src="losAnglesPicture"/>
} else {
backgroundImage = <img src="genericPicture"/>
}
header = <div>
{ backgroundImage }
<h1>Welcome, {data.CurrentUser.firstName}!</h1>
<div>
}

return (
<div>
{ header }
<div>
)
...

Adding the Dashboard Stats Component

Next we'll add the Thought Industries dashboard stats component. This component will display the number of courses the user has started, completed, has available, and the number of comments a user has made.

We'll install the component by running this command:

npm i @thoughtindustries/dashboard-stats

Then add the component below our header component.

/components/Dashboard.tsx
...

return (
<div>
{ header }
<DashboardStats/>
<div>
)
...

Adding Certificates

Next we can also add some logic for rendering data about the user's certificates. To do this, we'll add the UserCertificates query to the dashboards_query we defined at the top of our component

/components/Dashboard.tsx
// note: this code is strictly for reference and is largely unstyled
...

let certificates;
if (data) {
...
certificates = data.UserCertificates.map((cert, i) =>
return <div>
<h1>{cert.certificateTemplate.title}</h1>
<img src={cert.source}/>
</div>
)
...
}

return (
<div>
{ header }
<DashboardStats/>
{ certificates }
<div>
)
...

Part 3: Routing and Maintenance

Option 1: Using the Dashboard for all Panoramas

Awesome, our custom dashboard component is now complete! We want to use this dashboard for all of our panoramas so we will route our dashboard component to /learn/dashboard where is will replace the default Ti dashboard.

/pages/learn/dashboard.page.tsx
import React from 'react';
import { Dashboard } from '../components/dashboard'

function Page() {
return (
<Dashboard/>
);
}

export { Page };

There is some maintenance required with this approach where every time a new panorama gets added to the learning instance, the code will have to be adjusted to support this new panorama.

Option 2: Using the Dashboard for just the Main Site

Another option is using this custom dashboard for the main site and keeping the panorama dashboards as is. To do this, we'll need to route our new Helium dashboard to a different url, such /dashboard for example. Our panorama dashboards will remain on the url /learn/dashboard.

/pages/dashboard.page.tsx
import React from 'react';
import { Dashboard } from 'components/dashboard'

function Page() {
return (
<Dashboard/>
);
}

export { Page };

In order to make this solution work, we'll also need to add redirects on both the Ti platform and in our code as well.