How to build a Home dashboard in React, Parcel and Alexa

Lindsay Jopson
Oct 6 · 6 min read
Current look of my Home Dashboard

I decided to take the benefits of in-built Alexa and blend them with some basic understanding of React into a personalised Home Dashboard.

Ever since I got an Amazon Echo, I have enjoyed having the ability to kick off my mornings by asking about the weather, traffic and playing music to kick the day off. I liked the idea of having a ‘home dashboard’ that wasn’t around ‘turning on the lights’ etc, but more around what I typically want to know in my household and my daily routines.

The result was a fairly simple React app, running in the browser of an Amazon Fire Tablet. The code of which is accessible on Github here.

Pre-requisites:

  • Basic understanding of React
  • Node installed

Where to start

Firstly you need to create the React project barebones.
Essentially it’s three files. Two of which I put in a src folder.
src/index.html src/index.js & package.json

src/index.html

In the body of your src/index.html file, place in the following.

<div id="root"></div>  
<script src="index.js"></script>

This will mean when the index.js file is executed, it will place the React container and all of the /widgets you have listed, into the #root div.

src/index.js

Next, you will need to add the index.js file. This is the ‘engine’ of your app. This is where a fundamental understanding of React is required.

The contents of your src/index.js file is the following:

import * as React from "react";
import { render } from "react-dom";
const App = () => (
<>
My Home Dashboard
</>
);
render(<App />, document.getElementById("root"));

To run through this line by line:

import * as React from "react";
import { render } from "react-dom";

This is pulling in the react library &react-dom to enable your app to render(<App/>, document.getElementById("root"));

Next key portion is:

const App = () => (
<>
My Home Dashboard
</>
);

At this stage, everything that is added between the two <> & </> is going to be rendered in the browser after executing npm start

Currently shown in browser

package.json

This is where the ‘magic’ happens. This is where React and Parcel are all pulled into play and the node scripts are placed:

{
"name": "dhome",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "parcel ./src/index.html"
}
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"parcel-bundler": "^ 1.12.3",
"react": "^ 16.9.0",
"react-dom": "^ 16.9.0"
}
"devDependencies": {
"parcel-bundler": "^ 1.12.3"
}
}

After placing this in the root of your directory, execute npm install & npm start . This will download and install parcel-bundler, react & react-dom and run the parcel start script via npm start which will create a local dev server. Compile your src/index.js and make your /src/index.html accessible via localhost:1234


Build widgets

I decided to use a ‘widget’ system to my dashboard. There is no reason you couldn’t just put these directly into your index.js file, however for extendability and to allow for switching between different things showing in the future.

All of my widgets are stored under /src/widgets . The first widget I built was a ‘countdown’ widget. Our house typically has something going on we are excited for. At this moment in time, it’s counting down to the annual Christmas Party we host!

To do this, it was a simple coding exercise. Take the current date, the date your event is on, and display the difference…

In reality, it looks like this. First, create /src/widgets/countdown/index.js

import React from "react";export class CountdownWidget extends React.Component {
render() {
return (
<div className="widget countdown">
<div className="heading">Christmas Party</div>
<div className="count">100</div>
<div className="meta">Days</div>
</div>
);
}
}

Now we need to extend this to create the ‘real’ countdown, not just 100.

To do this, you need to add this code above the render() function.

constructor(props) {
super(props);
const then = new Date(2019, 12, 15);
const today = new Date();
const count = Math.abs(Math.round((today - then) / (1000 * 60 * 60 * 24)));
this.state = {
count: count
};
}
componentDidMount() {
setInterval(() => {
const then = new Date(2019, 12, 15);
const today = new Date();
const count = Math.abs(Math.round((today - then) / (1000 * 60 * 60 * 24)));

this.setState({
count: count
});
}, 3600000);
}
render() {
...

The key things to notice in this code block would be:

  • then The date you are counting down to
  • today Todays Date
  • this.state This essentially forms the ‘shape’ of the component state, which enables us to alter it and query it later in the code.
  • this.setState This updates the component state with a new variable.

I have chosen to use a setInterval on this, while it's not necessary, it just means that every 24 hours, the count variable should update without needing to refresh the entire dashboard.

Now simply update your render function with:

<div className="count">{this.state.count}</div>

Add the countdown to your dashboard

To add the CountdownWidget to your dashboard. Open index.js and add the following lines:

import * as React from "react";
import { render } from "react-dom";
import { CountdownWidget } from "./widgets/countdown";

And within the App const

const App = () => (
<CountdownWidget />
);

You should now see the following in your browser:

Add some style

I personally use Sass files to do this, but this is totally up to you.

To do this I have created a /src/styles folder in the root dir. Then add various _filename.scss ‘s underneath that. The beauty of Parcel is it will compile .scss & .jsfiles straight out of the box for you, and automatically recompile them every time you save. By adding:

if (module.hot) {
module.hot.accept();
}

to your root index.js you will see your browser update these recompiled artefacts straight out of the box!

hot reloading in action

The Alexa bit…

So this is a bit of a cheat. Rather than trying to integrate the Alexa API into my dashboard, I have decided to leverage a device that already has this built-in. The Amazon Fire Tablet. These come with a web browser which will basically, point to your dashboard you have just created. Now you can have your dashboard running, while still being able to call out “Alexa, play Coldplay” without needing to touch your dashboard.

Build widgets and have fun!

You now have everything you need to start building widgets. To get you started I have a couple I have already done available on my GitHub. Feel free to pull these, update what you need and go from there! I would love to see what widgets you add, so feel free to open a PR to this repo and we can potentially make some cool changes and updates going forward.

JavaScript in Plain English

Learn the web's most important programming language.

Lindsay Jopson

Written by

Engineering Manager

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade