@seatlayer/js 0.12.0 → 0.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,7 +46,7 @@ Svelte → `onMount` / `onDestroy`. Angular → `ngAfterViewInit` / `ngOnDestroy
46
46
  realtime organizer cockpit. Mint a short-lived, event-scoped `mse_` token from
47
47
  your backend, bound to the browser's exact origin and only the capabilities it
48
48
  needs. The shared surface owns Monitor, Inspect, Block/unblock, fullscreen,
49
- presence, exact section revenue, sales velocity, and its heat overlay.
49
+ presence, exact section revenue, sales velocity, and a clearly explained **Sales momentum** overlay.
50
50
 
51
51
  ```js
52
52
  import { SeatManager } from '@seatlayer/js';
package/dist/index.cjs CHANGED
@@ -2387,6 +2387,10 @@ var CSS2 = `
2387
2387
  .slm-sectionhead{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-top:18px}
2388
2388
  .slm-windows{display:flex;gap:3px;padding:2px;border:1px solid var(--slm-line);border-radius:8px;background:var(--slm-surface)}
2389
2389
  .slm-window{padding:4px 6px;border-radius:6px;font-size:10px;font-weight:800;color:var(--slm-muted)}.slm-window.on{background:var(--slm-accent);color:var(--slm-accent-ink)}
2390
+ .slm-momentumhelp{margin:10px 0 14px;padding:10px;border:1px solid rgba(244,183,64,.28);border-radius:10px;background:rgba(244,183,64,.07)}
2391
+ .slm-momentumhelp[hidden]{display:none}.slm-momentumscale{display:flex;align-items:center;gap:7px;color:var(--slm-muted);font-size:10px;font-weight:750;text-transform:uppercase;letter-spacing:.07em}
2392
+ .slm-momentumgradient{height:6px;min-width:64px;flex:1;border-radius:999px;background:linear-gradient(90deg,#f4b740,#ef4444)}
2393
+ .slm-momentumcopy{margin-top:7px;color:var(--slm-muted);font-size:11px;line-height:1.45}
2390
2394
  .slm-inspect-card{padding:12px;border:1px solid var(--slm-line);border-radius:12px;background:var(--slm-surface)}
2391
2395
  .slm-inspect-label{font-size:24px;font-weight:850;letter-spacing:-.02em}.slm-inspect-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:14px}
2392
2396
  .slm-inspect-grid span{display:block;color:var(--slm-muted);font-size:10px;text-transform:uppercase;letter-spacing:.08em}.slm-inspect-grid b{display:block;margin-top:3px;font-size:12.5px}
@@ -2515,11 +2519,12 @@ var SeatManager = class {
2515
2519
  }
2516
2520
  this.buildRenderer();
2517
2521
  this.buildSectionOptions();
2518
- await Promise.all([
2522
+ const [, controlRoom] = await Promise.all([
2519
2523
  this.resnapshot(),
2520
2524
  this.refreshControlRoom().catch((err) => this.opts.onError?.(err))
2521
2525
  ]);
2522
- this.api.log(this.key, { limit: 24 }).then((page) => this.seedFeed(page.entries)).catch(() => {
2526
+ if (controlRoom?.activity) this.seedFeed(controlRoom.activity);
2527
+ else this.api.log(this.key, { limit: 24 }).then((page) => this.seedFeed(page.entries)).catch(() => {
2523
2528
  });
2524
2529
  this.connect();
2525
2530
  this.startFeedClock();
@@ -3025,7 +3030,8 @@ var SeatManager = class {
3025
3030
  release: "released",
3026
3031
  expire: "expired",
3027
3032
  block: "blocked",
3028
- unblock: "unblocked"
3033
+ unblock: "unblocked",
3034
+ unbook: "cancelled"
3029
3035
  };
3030
3036
  const stByAction = {
3031
3037
  hold: "held",
@@ -3033,7 +3039,8 @@ var SeatManager = class {
3033
3039
  release: "free",
3034
3040
  expire: "free",
3035
3041
  block: "blocked",
3036
- unblock: "free"
3042
+ unblock: "free",
3043
+ unbook: "free"
3037
3044
  };
3038
3045
  for (const e of entries) {
3039
3046
  const label = e.labels[0];
@@ -3090,7 +3097,9 @@ var SeatManager = class {
3090
3097
  </div>
3091
3098
  <span class="slm-live"><span class="slm-live-dot"></span><span data-ref="livetext">CONNECTING</span></span>
3092
3099
  <div class="slm-bar-actions">
3093
- <button class="slm-barbtn" data-ref="heat" aria-pressed="false">Heat</button>
3100
+ <button class="slm-barbtn" data-ref="heat" aria-pressed="false"
3101
+ aria-label="Sales momentum overlay off"
3102
+ title="Highlight sections selling fastest in the selected time window">Sales momentum</button>
3094
3103
  <button class="slm-barbtn" data-ref="fullscreen" title="Full screen (F)" aria-keyshortcuts="F">Full screen</button>
3095
3104
  </div>
3096
3105
  <div class="slm-kpis" data-ref="kpis"></div>
@@ -3169,7 +3178,19 @@ var SeatManager = class {
3169
3178
  if (!button) return;
3170
3179
  button.classList.toggle("on", this.heatEnabled);
3171
3180
  button.setAttribute("aria-pressed", String(this.heatEnabled));
3172
- button.textContent = this.heatEnabled ? "Heat on" : "Heat";
3181
+ button.setAttribute("aria-label", `Sales momentum overlay ${this.heatEnabled ? "on" : "off"}`);
3182
+ button.setAttribute("title", `${this.heatEnabled ? "Hide" : "Highlight"} sections selling fastest in the selected time window`);
3183
+ button.textContent = "Sales momentum";
3184
+ this.paintMomentumHelp();
3185
+ }
3186
+ paintMomentumHelp() {
3187
+ const help = this.els.rail?.querySelector('[data-ref="momentumhelp"]');
3188
+ if (!help) return;
3189
+ help.hidden = !this.heatEnabled;
3190
+ const copy = help.querySelector('[data-ref="momentumcopy"]');
3191
+ if (!copy) return;
3192
+ const hasRecentSales = this.controlRoomSnapshot?.velocity.bySection.some((row) => row.netBooked > 0);
3193
+ copy.textContent = hasRecentSales ? "Warmer sections have more completed bookings, adjusted for section size. Holds and viewers are not counted." : `No completed bookings in the last ${this.trendWindowMinutes} minutes.`;
3173
3194
  }
3174
3195
  paintFullscreenButton() {
3175
3196
  if (!this.els.fullscreen) return;
@@ -3226,6 +3247,10 @@ var SeatManager = class {
3226
3247
  ${[5, 15, 30, 60].map((window2) => `<button class="slm-window" data-window="${window2}">${window2}m</button>`).join("")}
3227
3248
  </div>
3228
3249
  </div>
3250
+ <div class="slm-momentumhelp" data-ref="momentumhelp" ${this.heatEnabled ? "" : "hidden"}>
3251
+ <div class="slm-momentumscale"><span>Warm</span><span class="slm-momentumgradient"></span><span>Hot</span></div>
3252
+ <p class="slm-momentumcopy" data-ref="momentumcopy"></p>
3253
+ </div>
3229
3254
  <div class="slm-sectionlist" data-ref="sections"></div>
3230
3255
  <p class="slm-eyebrow">Activity</p>
3231
3256
  <div class="slm-feed" data-ref="feed"></div>
@@ -3241,6 +3266,7 @@ var SeatManager = class {
3241
3266
  this.recomputeTallies();
3242
3267
  this.paintMonitorInsights();
3243
3268
  this.paintTrendWindow();
3269
+ this.paintMomentumHelp();
3244
3270
  this.paintFeed();
3245
3271
  }
3246
3272
  paintMonitorInsights() {
@@ -3277,6 +3303,7 @@ var SeatManager = class {
3277
3303
  </div>`;
3278
3304
  }).join("") : '<div class="slm-empty">No section metrics are available for this chart.</div>';
3279
3305
  this.paintTrendWindow();
3306
+ this.paintMomentumHelp();
3280
3307
  }
3281
3308
  applyHeatOverlay() {
3282
3309
  const snapshot = this.controlRoomSnapshot;