Web Portal UX
Admin portal design — device management, talkgroup control, user administration, key rotation, and GPS map.
Web Portal UX
The web portal (packages/portal) is a React admin interface. It is used by ground operations administrators, not by pilots. It runs in a browser on a laptop or desktop.
The portal consumes the same REST API as the mobile app. It requires an admin-role JWT.
User Roles and Access
| Role | Access |
|---|---|
admin | Full portal access — all sections listed below |
user | No portal access — portal redirects to login on 403 |
Admin users log in via the same POST /auth/login endpoint as mobile users. The portal stores the JWT in localStorage and includes it on every API request.
Navigation Structure
The portal is a single-page app with a left sidebar nav:
Dashboard
Landing page after login. Shows system health at a glance:
- Total registered devices / active devices
- Total talkgroups / total memberships
- Recent connections (last 10 WebSocket join events — from server logs, not a live feed in v1)
- Server reachability (ping check against
GET /ping)
The dashboard is read-only.
Devices
Full device registry. Maps to GET /devices (admin only).
Device List
Columns: Name, Site, Serial, Status (active/inactive), Created At.
An Active / Inactive toggle on each row calls PATCH /devices/:id/status. Disabling a device prevents it from authenticating — its JWT will still validate until expiry, but new logins will fail because the password check looks up the user's linked device and checks active: true.
There is no JWT revocation in v1 — disabling a device does not immediately kick an active WebSocket session. For immediate revocation, restart the server (all WebSocket connections drop) or wait for the client to reconnect and re-authenticate.
Device Detail
Clicking a row shows:
- Full device info
- Linked user (username, role)
- Last known GPS fix (from
GET /devices/:id/gps) - GPS history (not yet implemented — would require a pagination endpoint)
Talkgroups
Maps to the talkgroup REST endpoints.
Talkgroup List
Lists all talkgroups in the system. Each row: Name, Member Count, Rotation Counter, Created At.
Actions per row:
- View members — opens a member list panel
- Delete — calls
DELETE /talkgroups/:id. Cascades to all memberships. Prompts for confirmation before executing.
Create Talkgroup
A form at the top of the list: Name field + Create button. Calls POST /talkgroups. The portal then refreshes the list.
Talkgroup Detail — Key Rotation
From the detail view, an admin can rotate the encryption key for a talkgroup:
- Click Rotate Key
- Confirmation dialog: "This will increment the rotation counter. All clients must re-derive their session key. Clients that have not updated will fail to decrypt audio."
- Confirm → calls
POST /keys/rotatewith the talkgroup ID rotation_counterincrements. New value is displayed.
See Key Management → for the full rotation flow.
Users
Maps to GET /users (admin only, returns id/username/role — no password hashes).
Displays a table of all registered users. Per row: Username, Role, Linked Device (if any), Created At.
In v1 there is no user creation UI in the portal — users self-register via POST /auth/register on the mobile app or via curl. The portal is read-only for user records.
A Reset Password action is on the roadmap but not implemented in v1.
GPS Map
A live moving map showing the last known position of all active devices.
Implementation:
- On load, fetches
GET /devicesto get all device IDs, then callsGET /devices/:id/gpsfor each. - Renders pins on a map tile layer (Leaflet.js with OpenStreetMap tiles).
- Auto-refreshes every 30 seconds (no WebSocket subscription from the portal in v1).
Each pin shows: device name, site, last update timestamp.
The GPS map is read-only and polling-based in v1. A real-time map (WebSocket-driven) is a v2 feature.
Design Principles for the Portal
The portal is a utility interface used by operators at a desk, not under flight stress. Different constraints than the mobile app:
- Density over minimalism — tables with many columns are appropriate here.
- Confirmation dialogs for destructive actions (delete talkgroup, rotate key, disable device).
- No realtime requirement — polling and page refreshes are acceptable for admin operations.
- Standard web patterns — breadcrumb navigation, table pagination, form validation, toast notifications for success/error.
The portal does not use the same design constraints as the mobile app. It follows standard admin dashboard conventions rather than HIG.