Skip to content

Dashboard: animated first-visit help overlay#10

Merged
StrangeNoob merged 8 commits into
mainfrom
help-overlay
Jun 9, 2026
Merged

Dashboard: animated first-visit help overlay#10
StrangeNoob merged 8 commits into
mainfrom
help-overlay

Conversation

@StrangeNoob

Copy link
Copy Markdown
Owner

Summary

Adds an animated first-visit help overlay to the dashboard so visitors landing on the live site immediately understand what Relay is. Frontend-only — no Go/engine changes (git diff of internal/, cmd/, go.mod, go.sum is empty); the server just embeds the rebuilt web/dist.

  • HelpOverlay — a modal that auto-opens on a visitor's first load: a one-line "what is Relay," a pure-CSS animated job-lifecycle (Ready → In-flight → done, with a retry→Delayed loop and a Dead-letter branch — terracotta dots = jobs, gold = a retry waiting out backoff), and three concept captions (atomic claim / retry+backoff / crash-safe). Copy is accurate to the engine (single-Lua atomic claim, full-jitter backoff, reaper recovery, at-least-once — no exactly-once overclaim).
  • Always-visible ? in the sidebar reopens it anytime.
  • lib/help.ts — a pure, unit-tested localStorage gate (shouldAutoOpen/markSeen); first-visit only, privacy-mode safe (never throws).
  • a11yrole="dialog", aria-modal, aria-label, Esc + backdrop close, type="button" controls, focus-into-modal on open + restore on close, and a prefers-reduced-motion fallback that shows a static (still legible) diagram.
  • Pure CSS keyframes — no new dependency (consistent with the dashboard's hand-rolled-SVG stance).

Once merged, Railway's main-linked server service auto-rebuilds and the overlay goes live at https://server-production-840f.up.railway.app.

Design & plan

  • Spec: docs/superpowers/specs/2026-06-09-relay-dashboard-help-overlay-design.md
  • Plan: docs/superpowers/plans/2026-06-09-relay-dashboard-help-overlay.md

Test plan

  • lib/help.test.ts (vitest) — shouldAutoOpen (absent→true, set→false, throw→true) + markSeen (writes, swallows throw); 13 frontend tests pass
  • tsc --noEmit strict, vite build, and git diff --exit-code -- dist all clean (committed dist in sync)
  • go build ./..., go vet ./..., gofmt -l web/ clean; go test ./web/ -run TestHandler passes (embed/SPA fallback unaffected)
  • No Go engine changes (frontend + dist only)

@StrangeNoob

Copy link
Copy Markdown
Owner Author

Code review

Found 1 issue:

  1. closeHelp is an unmemoized inline function passed as HelpOverlay's onClose. Since App re-renders ~every second from the SSE ticker, closeHelp gets a new identity each render, so HelpOverlay's useEffect([open, onClose]) re-runs every tick while the overlay is open — tearing down/re-adding the Esc listener and, worse, re-capturing previouslyFocused (which becomes the modal itself after the first focus). On close, focus is restored to the unmounted modal instead of the triggering element, defeating the focus-restore behavior. The overlay auto-opens on first visit, so this reliably triggers. Fix: wrap closeHelp in useCallback(…, []).

relay/web/src/App.tsx

Lines 78 to 83 in 7af73e9

const closeHelp = () => {
markSeen(localStorage);
setHelpOpen(false);
};

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@StrangeNoob StrangeNoob merged commit 8624f0c into main Jun 9, 2026
4 checks passed
@StrangeNoob StrangeNoob deleted the help-overlay branch June 9, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant