auth-yes/tasks/complete/2026-0826.03.jul.feat.ui.sessions-layout-drawer-machine-2156.ph3.md
google-labs-jules[bot] d057e080d3 feat(ui): implement 2-state workshop drawer machine and refine session page hierarchy
- Moved `EventCockpitDeck` below main header in `SessionsPage.tsx`
- Refactored `WorkshopDrawer.tsx` to strictly use a 2-state display toggle (`#eventCreateState` and `#eventHandoffState`)
- Added `aria-label`s to copy buttons for accessibility
- Configured `#status-banner` with `role="status"` and `aria-live="polite"`
- Fixed mobile title text wrapping on `#createdEventTitle`
- Fixed script emoji injection logic to prevent double emojis
- Added JS reset logic in `closeDelegateDrawer` to restore drawer states and clear form data

Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
2026-08-27 00:12:50 +00:00

4.4 KiB

TASK METADATA

  • Target Files: ui/components/SessionsPage.tsx, ui/components/sessions/WorkshopDrawer.tsx, ui/components/sessions/SessionsScript.tsx, ui/ui_scripts.test.ts
  • Core Objective: Overhaul visual hierarchy of /dashboard/sessions and enforce strict 2-state mutually exclusive rendering in WorkshopDrawer.tsx.
  • Dependencies: None.
  • Additional Important Notes: Must use pure vanilla JavaScript for DOM manipulation (no React/framework state). Ensure copy pills trigger accessible notifications (aria-live/toast) with explicit aria-label tags. Fix double emoji bug in JS. Ensure mobile title wrapping. All changes must pass ui/ui_scripts.test.ts.

2. Architectural Considerations & Risks

  • Risks:

    • DOM Manipulation Regression: Because this UI operates strictly on vanilla JavaScript, changing the layout and grouping DOM elements within new containers (#eventCreateState and #eventHandoffState) risks breaking existing DOM ID bindings in SessionsScript.tsx. All existing DOM IDs must be preserved.
    • Test Compatibility: Client scripts are validated via hermetic execution in ui/ui_scripts.test.ts. Script modifications must remain structurally valid and strictly avoid any external framework dependencies.
    • Mobile Layout Breakage: When fixing long titles to wrap correctly, CSS properties overflow-wrap: break-word and word-break: break-word must be paired with bounded max-widths to prevent horizontal container stretching.
  • Alternatives:

    • The container-based 2-state machine approach for WorkshopDrawer.tsx is native and robust. Using a class-based toggle was considered, but explicit element display manipulation is clearer for the specific 2-state requirement.

3. Proposed Implementation

Phase 1: Page Hierarchy Update (ui/components/SessionsPage.tsx)

  1. Header Block Relocation: Move the main header block (<h1>Active Sessions & Passes</h1>, subtitle, and [ 🔑 Delegate Session ] button) to be the uppermost visible element below the #status-banner.
  2. Section Hierarchy:
    • Section 1: EventCockpitDeck (Event Passes cards). If 0 event passes exist, render a clean empty state or let the deck cleanly return null without an orphaned section heading.
    • Section 2: SessionTable / SessionDeck (Active Sessions).

Phase 2: WorkshopDrawer 2-State Machine (ui/components/sessions/WorkshopDrawer.tsx)

  1. State 1 (#eventCreateState): Wrap the initial creation form (#eventForm), inputs, submit button, and cancel button in <div id="eventCreateState" style="display: block;">.
  2. State 2 (#eventHandoffState): Wrap the credential cards in <div id="eventHandoffState" style="display: none;">.
    • Render the 3 distinct cards (PIN + /join, Direct Link, CLI 1-Liner).
    • Add explicit aria-label on copy buttons ("Copy Universal PIN", "Copy Direct Link", "Copy Terminal curl command").
    • Render a single "Dismiss" button at the bottom of #eventHandoffState.
  3. Drawer Title Transition: Add id="eventDrawerHeaderTitle" to the top header so JavaScript can transition it from "New Event Pass" \rightarrow "Event Pass Active".
  4. Mobile Title Wrapping: Ensure createdEventTitle has overflow-wrap: break-word; word-break: break-word; with safe max-width.

Phase 3: JavaScript Logic Update (ui/components/sessions/SessionsScript.tsx)

  1. State Toggling: Update handleCreateEvent so that upon successful creation:
    • Sets document.getElementById('eventCreateState').style.display = 'none'.
    • Sets document.getElementById('eventHandoffState').style.display = 'block'.
    • Updates document.getElementById('eventDrawerHeaderTitle').textContent = 'Event Pass Active'.
  2. Drawer Reset: When the drawer is closed or dismissed, reset state back:
    • #eventCreateState.style.display = 'block'
    • #eventHandoffState.style.display = 'none'
    • Reset form inputs and restore header to 'New Event Pass'.
  3. Emoji Fix: Remove the hardcoded '🎟️ ' prefix from the event title injection line: document.getElementById('createdEventTitle').textContent = ev.name + ' Live!';

Phase 4: Quality Gates

  1. Run deno fmt and deno task lint.
  2. Run Deno tests: deno test --allow-all (specifically validating ui/ui_scripts.test.ts).