# Dashboards

contexts.live has three dashboards — one web-based per-org operator hub, one web-based system admin panel, and one shell-based tool launcher.

---

## Org dashboard

**`https://contexts.live/org/{slug}/`**

Requires client or admin login. The operator's home page for each organisation — shows everything available for an org in one place.

Opening the dashboard URL (`/org/{slug}/`) serves `cx-org-index.html` via symlink.

### Pack selector

At the top of the page, a dropdown lists all packs in `org/{slug}/packs/`. Selecting a pack appends `?pack=packname` to every page link and QR code generated by the dashboard.

Pack names include the title and composer from the pack's meta, plus the pack ID.

### Page sections

Pages are scanned from three directories in order:

```
org/{slug}/local/     — org-specific custom pages (if any)
org/{slug}/user/      — shared audience display pages
org/{slug}/client/    — shared operator/control pages
```

Within each directory, pages are grouped by `cx-purpose`:

```
Display   — cx-purpose: display
Control   — cx-purpose: control or monitor
```

Empty sections are silently omitted. Each section heading shows e.g. `User — Display` or `Client — Control` when multiple directories are scanned.

Each card shows:
- Page title (from `<title>` tag, stripping the `contexts.live —` prefix)
- Description (from `cx-description` meta tag)
- Content-type tags (dotted `data-cx` tokens, e.g. `st.text`, `score.image`)
- A decorative QR thumbnail

Clicking a card opens the page in a new tab with the current pack and any param bar settings appended.

### Pill filters

If pages in a section have content-type tags, a pill filter row appears. Click a pill to show only pages with that tag. `all` resets the filter.

### QR overlay

Tapping the QR thumbnail on a card opens a full-size scannable QR code for that page URL, with the title and URL shown below.

### Print QR sheet

Each section heading has a **Print QR sheet →** link. This opens `cx-qr-sheet.html` filtered to that section's purpose, with the current pack pre-set.

### Param bar

Fixed at the bottom of the page. Settings here are appended to every page link opened from the dashboard:

| Control | URL param | Effect |
|---|---|---|
| Socket | `?socket=false` | Simulation mode — pack plays automatically from timecodes |
| Speed | `?speed=N` | Simulation playback speed (0.5×, 1×, 2×, 4×) — only shown in Simulate mode |
| Lang | `?lang=xx` | Set display language (en, de, mi, fr, it) |
| Start cue | `?startCue=N` | Start from line N |

### Media section

If `org/{slug}/media/` contains video files (mp4, mkv, avi, mov, webm), they appear in a Media section below the page cards, grouped by subfolder.

### Tools section

Links to the org's tools: Subtitle Editor, Pack Migrator, Pack Merge, Documentation.

### Live status

A status bar appears below the header showing the current state of the org's socket namespace, updated every 10 seconds:

- **Green dot** — one or more clients connected; shows connected count, seconds since last cue, and current pack
- **Grey dot** — no clients connected; shows time since last cue if available, otherwise "idle"

Data comes from `GET /{slug}/status` on cx-server.

### Implementation

`cx-org-index.html` is a symlink target at `org/{slug}/index.html`. It imports `cx-index.js` and uses `buildPageIndex()`, `scanPacks()`, and `slugFromPath()`. Config is loaded from `../../config.json` (i.e. `org/{slug}/config.json`).

---

## Admin dashboard

**`https://contexts.live/cx/cx-admin-dashboard.html`**

Requires admin login. System-wide overview — not org-specific.

### Sections

**Quick links** — contexts.live home page and documentation.

**Organisations** — live list of all orgs, loaded via `scanOrgs()` from `cx-index.js`. Each card shows the org name, slug, pack chips, and a live status indicator updated every 10 seconds. The status dot is green when clients are connected, grey when idle. Connected count, time since last cue, and active pack are shown when available.

Status is fetched from `GET /status` on cx-server, grouped by server — each unique server in the org configs is fetched once per poll. Server defaults to `window.location.hostname:8008` if not in config.

**System tools** — links to system-scoped tools (no org slug):

| Tool | Path |
|---|---|
| Subtitle Editor | `/cx/tools/editor/` |
| Pack Merge | `/cx/tools/cx-merge.html` |
| Pack Migrator | `/cx/tools/cx-pack-migrate.html` |
| User Admin | `/cx/tools/cx-user-admin.html` |
| Login page | `/cx/tools/cx-login.html` |

**Maintenance** — reference cards for SSL renewal, startup/shutdown, and git. These are informational stubs — inactive cards, not clickable links.

---

## Engagement viewer

**`https://contexts.live/org/{slug}/tools/cx-engagement.html`**

Requires client or admin login. Per-org audience analytics driven from the monitor JSONL logs.

### Date picker

On load, the viewer lists available log files from `org/{slug}/logs/` via nginx autoindex, selects the most recent, and loads it automatically. Other dates can be selected from the dropdown. Falls back to `.jsonl.gz` if the plain file is not found (supporting future log compression).

### Summary strip

Four counts across the top: unique clients, cue events, packs seen, languages seen.

### Clients over time

Canvas chart. Events are bucketed by line number — entries within 3 seconds of each other on the same line are merged into one event. Each event plots:

- **Solid line** — distinct IP count (unique clients)
- **Dashed line** — total log entry count (clients × pages/tabs)
- **Shaded band** — area between the two lines

X axis is UTC time; day boundaries shown as dashed vertical lines. Hover for exact values.

### Engagement chart

Canvas chart. One row per unique combination of `client IP × language × pack × page`. Each cue event appears as a tick mark, coloured by language.

Sort order (and column order in the label area) is controlled by the dropdown:

```
Client → Lang → Pack → Page
Lang → Pack → Page → Client
Pack → Lang → Page → Client
Page → Lang → Pack → Client
```

Hover over a tick for timestamp, client, language, pack, page, and line number.

### Engagement by pack

Table per pack, sorted by first appearance. Summary row shows client count and median session duration. Per-client rows show:

| Client | Sessions | Total duration | Pages | Languages |
|---|---|---|---|---|

Sessions are split when a client gap exceeds 10 minutes. Page column shows the sequence of distinct pages visited.

---

## Shell dashboard

**`cx/tools/cx-shell.sh`**

Interactive terminal menu for server-side tasks. Run from anywhere — resolves the site root from `/cx/.cx-config.json`.

```bash
bash /path/to/cx/tools/cx-shell.sh
```

### Menu

```
1  cx-build.sh       — bundle + obfuscate cx.js
2  cx-org-create.sh  — create new org
3  cx-inventory.js   — scan all orgs and packs
4  cx-export.js      — export pack to TSV/CSV
5  git commit        — services/
6  git commit        — site root
```

### Behaviour

Tools with no required arguments (inventory, build) show a confirm prompt then run.

Tools that need arguments (org-create, export) prompt for each argument with a hint, then run.

Git entries show a short `git status` preview before asking for the commit message. Both repos are committed with `git add -A` — all changes staged in one step.

After each tool runs, output remains visible and the shell waits for Enter before returning to the menu.

### Adding tools

Add a new handler function and a new `case` entry in the main loop. Follow the existing pattern — `confirmed` for no-arg tools, `prompt_arg` for each required argument.
