Vue 3 SPA for PlaceBrain — places, devices, live telemetry, alerts.
The web client for PlaceBrain. It talks REST to the gateway for CRUD and Auth, and subscribes over MQTT-over-WebSocket for live telemetry and alerts. The design is minimalist, theme-aware (light/dark), and laid out for both desktop (left sidebar) and mobile (bottom navbar).
PlaceBrain is an open-source IoT platform for smart buildings. See the organization profile for the full architecture.
- Talks only to gateway over HTTP (
VITE_API_URL, proxied by Traefik on/api/*). - Fetches short-lived MQTT credentials from
POST /api/mqtt/credentialsand connects to EMQX over WebSocket (/mqtt). - Subscribes to
placebrain/{placeId}/device/{deviceId}/telemetryandplacebrain/{placeId}/alertsfor live updates.
- Vue 3, TypeScript, Vite
- TanStack Query v5 for server state
- Pinia for UI state
- Axios — Bearer token + 401 → refresh → retry interceptor
- mqtt.js — realtime
- Tailwind CSS v4 via
@tailwindcss/vite - lucide-vue-next icons, uplot charts
- ESLint 9 + Prettier,
vue-tsctype-check
src/
├── app/ Providers (router, pinia, TanStack Query), layouts, global styles
├── pages/ Login, Register, VerifyOtp, Dashboard, Places, PlaceDetail,
│ Devices, DeviceDetail, DeviceEditor, SensorEditor, Alerts, Profile
├── widgets/ Sidebar, MobileNavbar, PlaceTabs, SensorsPanel, ActuatorsPanel,
│ ChartsPanel, PlaceCardGrid
├── features/ Auth forms, CRUD modals, manage-devices/sensors/actuators, theme toggle
├── entities/ user, place, device, member (types, TanStack Query hooks, UI)
└── shared/ UI kit (UiButton, UiInput, UiModal, UiConfirmDialog, UiOtpInput, ...),
API client, query keys, composables (useMqtt, useBreakpoint), stores, config
- Light/dark themes via CSS variables +
darkclass on<html>. - Minimalist, no gradients. Accent
#6E9EF9, danger#E85A4F. - Inter for body, Space Grotesk for headings (
font-headingclass). - Colors are referenced only through
var(--color-*); hardcoded Tailwind palette classes are avoided. - Surface convention:
--color-surfacefor cards/sidebars/modals,--color-surface-elevatedfor the page background. Cards always stand out from the background.
- Destructive actions go through
<UiConfirmDialog>, never nativeconfirm(). - Post-mutation feedback via
useToast()on authenticated pages; inline on auth pages (login/register/verify-otp). - Icon-only buttons carry an
aria-label. Modals arerole="dialog"with focus trap. - Breakpoint 768px: desktop sidebar (
w-64/w-16collapsed, toggle viaCmd/Ctrl+B), mobile bottom navbar (h-16). - Auth flow: register → OTP email verification → login. Unverified users are redirected to
/verify-otp.
Full stack (recommended): clone infra and run make dev. The frontend is served by a Vite dev container behind Traefik; the SPA lives at http://localhost.
Service-only mode:
npm install
cp .env.example .env # set VITE_API_URL
npm run devYou still need a reachable gateway at VITE_API_URL.
npm run dev # Vite dev server
npm run build # vue-tsc -b + vite build
npm run preview # serve production build
npm run lint:fix # ESLint autofix
npm run format # Prettier
npx vue-tsc -b # standalone type-check (also run by CI)| Variable | Purpose |
|---|---|
VITE_API_URL |
Base URL of the gateway HTTP API (e.g. http://localhost) |
Apache License 2.0 — see LICENSE.