Pi IoT Academy
Phase 5 · Design the Dashboard

Phase 05

Design the dashboard.

The data is flowing and the database remembers it. Now you’ll give the platform a face: a touchscreen UI built in Vue 3 with charts, a sidebar, settings, and a full-screen kiosk mode that boots automatically. By the end of this phase the Pi looks like a real product, not a bunch of dev tools.

~60–90 min Difficulty: 2 / 3 Touch the screen! Frontend lesson

What changed

The frontend got serious.

Until Phase 4 the dashboard was a single placeholder page. In Phase 5 it becomes a four-page application:

Sensors (home)
The grid you already know — now bigger, touch-friendly, and tappable for charts.
Modules
Where future classroom projects (Phase 7+) will appear as tiles. Empty for now, with a preview of what’s coming.
Settings
Platform info and a live feed of recent system events — reboots, retention runs, and AI errors (Phase 6).
About
Stack, phase progress, credits.

Behind the scenes, you’re using:

  • Vue Router — client-side navigation between pages without a full reload.
  • Chart.js — the line charts that appear when you tap a sensor card.
  • Tailwind CSS — the design system. All colours, sizes, and spacing come from a small set of utility classes.
  • Composables — reusable Vue functions like useReadings() that share the live WebSocket between every page.
Why a single-page app?

If every navigation reloaded the whole page, you’d also drop the WebSocket every time. By doing routing in JavaScript, the connection stays open and the data keeps flowing as you move around.

Pull and rebuild

~10 minutes · on the Pi

The frontend image needs to be rebuilt because we’ve added Vue Router and Chart.js as dependencies.

terminal · on the Pi
cd /opt/iot-platform
git pull
docker compose build frontend
docker compose up -d

Building takes a couple of minutes the first time — npm install downloads ~130 packages. Watch the progress with:

terminal · on the Pi
docker compose logs -f frontend

Open http://pi-iot-XX.local/ on your laptop. You should see the new shell — a sidebar on the left with four icons, a top bar with the connection pill, and the sensor grid in the main area.

Checkpoint

Tour the four pages

~5 minutes

Click each icon in the sidebar in turn:

  • ◉ Sensors — the home grid. Cards for every sensor that’s ever published. Run the test publisher again if it’s empty.
  • ▦ Modules — placeholder tiles for the modules we haven’t built yet. They’re greyed out on purpose.
  • ⚙ Settings — platform info plus a live feed of system events.
  • i About — stack and phase summary.

Notice the URL changes (/, /modules, /settings, /about) but the page never fully reloads — the connection pill stays connected the whole time.

Try the back button

The browser’s back/forward buttons work as you’d expect — Vue Router uses the standard history.pushState API. This is what makes a SPA feel like a real website.

Checkpoint

Tap a sensor card

~5 minutes

Make sure the test publisher is running on your laptop (same command as Phase 4). On the Sensors page, click any card.

A modal opens with:

  • The sensor name and current value, big and clear.
  • A line chart showing the last ~100 readings, from oldest on the left to newest on the right.
  • The chart auto-updates as new readings arrive — you should see the right edge advance roughly every second.

Hover anywhere on the chart line (or tap on a touchscreen) to see the exact value and timestamp at that point.

Close the modal by clicking the × button or tapping outside the box. Try a different sensor — the chart should be a different colour for humidity than for temperature.

Where the chart data comes from

When the modal opens, the dashboard fires off GET /api/sensors/<id>/readings?limit=100. That’s the same endpoint you tried with curl in Phase 4 — you’re reusing the work.

Checkpoint

Read the audit log

~5 minutes

Go to Settings. Below the platform info you’ll see a Recent events section listing the latest 50 rows from system_logs.

You should see at least one boot event from the last time the API started. Click Refresh to reload the list. If the API has been up since 03:00 UTC, you’ll also see a reading_retention.run event — that’s the nightly clean-up.

Try this: SSH into the Pi and restart the API:

terminal · on the Pi
docker compose restart api

Wait 5 seconds, then click Refresh on the Settings page. A new boot event should appear at the top of the list with the current timestamp.

Why this matters

In a real lab, you’ll want to know why something happened. The audit log gives a per-event trail: when did the platform restart, when did retention last run, when did an AI call fail. Operators love this stuff.

Checkpoint

Touch test

~5 minutes · on the Pi’s touchscreen

The dashboard is meant to be used with fingers, not just a mouse. Open Chromium on the Pi’s 5″ touchscreen and visit:

browser · on the Pi
http://localhost/

Run through these checks with your fingertip:

  • Each sidebar icon is at least 48×48 pixels — you can hit it accurately on the first try.
  • Sensor cards are big enough to read from across the room — the value uses an extra-large font.
  • Tapping a card opens the modal smoothly. Tapping outside the modal or the close button dismisses it.
  • The Settings Refresh button is easy to hit and gives visible feedback when you press it.
  • Nothing depends on hovering the mouse — touch screens have no hover.
If a button feels too small

That’s a real bug. Touch targets below ~44 px are awkward even for adult fingers, terrible for primary-school students. Tell your teacher what you found — we’ll fix it.

Checkpoint

Kiosk mode autostart

~10 minutes · on the Pi

The final touch: the Pi should boot straight into the dashboard, full-screen, with no browser chrome or desktop visible. That’s called kiosk mode.

The repo has a script that sets it up:

terminal · on the Pi
cd /opt/iot-platform
./scripts/setup-kiosk.sh

The script:

  1. Installs Chromium if it’s missing.
  2. Writes a desktop autostart entry to ~/.config/autostart/iot-dashboard.desktop.
  3. Configures Chromium to launch full-screen pointing at http://localhost.

To test, reboot the Pi:

terminal · on the Pi
sudo reboot

After about a minute, the touchscreen should come up showing the dashboard full-screen — no taskbar, no address bar, just sensors.

Escape hatch

Need to get out of kiosk mode (e.g. to update software)? Press Alt+F4 on a USB keyboard to quit Chromium. The desktop comes back. To go back into kiosk mode, just relaunch Chromium or reboot.

If the dashboard doesn’t auto-launch

Different Pi OS versions use different desktop environments. Check that ~/.config/autostart/iot-dashboard.desktop exists. If it does and Chromium still doesn’t launch, try the older path ~/.config/lxsession/LXDE-pi/autostart — ask your teacher for the exact lines to add.

Checkpoint

Final verification

5 minutes

The platform should now look and feel like a real classroom IoT terminal. Tick everything below before declaring Phase 5 done.

Phase 5 sign-off

Phase 5 complete?

You’ve built a real product. Sensors, charts, settings, kiosk — the lot. Next phase: that big empty “Explain” spot we’re going to add to each card. Time to introduce Claude.

Phase 6: Ask Claude  →

(The button unlocks when every box above is ticked.)