SkyTalk Docs
UI / UX

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

RoleAccess
adminFull portal access — all sections listed below
userNo 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.


The portal is a single-page app with a left sidebar nav:

SkyTalk Admin
├── Dashboard
├── Devices
├── Talkgroups
│   └── [Talkgroup Detail]
├── Users
└── GPS Map

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:

  1. Click Rotate Key
  2. 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."
  3. Confirm → calls POST /keys/rotate with the talkgroup ID
  4. rotation_counter increments. 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 /devices to get all device IDs, then calls GET /devices/:id/gps for 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.

On this page