101 lines
4.5 KiB
Markdown
101 lines
4.5 KiB
Markdown
# TASK METADATA
|
|
|
|
- **Target Files:**
|
|
- `server/routes/events.ts`
|
|
- `ui/components/sessions/SessionsScript.tsx`
|
|
- `ui/components/sessions/EventCockpitDeck.tsx`
|
|
- `ui/components/SessionsPage.tsx`
|
|
- **Core Objective:** Resolve the final 4 untracked discrepancies identified
|
|
during the Phase 6 UI Audit (DOM desync, missing guest drawer payload, minor
|
|
typo, and missing sticky action bar).
|
|
- **Dependencies:** None.
|
|
- **Additional Important Notes:** This represents the final polish of the
|
|
`Sessions & Events` UX before moving on to backend relational decoupling and
|
|
P2P vouching.
|
|
|
|
---
|
|
|
|
## 2. Architectural Considerations & Risks
|
|
|
|
### Risks
|
|
|
|
1. **DOM Ingress Desync:** Currently, when an organizer clicks `[ 🔄 Rotate ]`,
|
|
the backend successfully updates both the `pin_code` and the `slug`. However,
|
|
the frontend JavaScript (`rotatePin`) only targets and updates the PIN on the
|
|
UI. The copy buttons for "Link" and "CLI" continue to hold the old slug
|
|
because their `onclick` handlers are hardcoded during SSR. _Risk_: If an
|
|
organizer rotates the credentials and then clicks "Copy Link", they will
|
|
mistakenly share the revoked link, leading to confusion and 404s.
|
|
2. **Guest Drawer Broken Meta Header:** The backend endpoint
|
|
`GET /api/events/:id/attendees` only returns
|
|
`{ success: true, attendees: [...] }`. The client script expects `data.event`
|
|
to populate the `Max Seats` and `Expires At` countdown. Because `data.event`
|
|
is undefined, the header is permanently stuck displaying
|
|
`0 / 0 Claimed Seats · ⏳ 0h 0m left`. _Risk_: Loss of critical event context
|
|
while managing guests.
|
|
3. **Scroll Fatigue:** The `[ Delegate Session ]` drawer trigger sits at the top
|
|
of `SessionsPage.tsx`. As the user accumulates multiple events or sessions,
|
|
scrolling down the page hides the primary action.
|
|
|
|
### Alternatives
|
|
|
|
- For the Sticky Action Bar, we could use CSS `position: sticky; top: 0;` on the
|
|
delegation tabs block in `SessionsPage.tsx`, ensuring the action is always
|
|
visible without creating a separate floating action button (FAB) which might
|
|
clutter mobile views.
|
|
- For the UI DOM rotation, we must assign `id` attributes to the Link and CLI
|
|
copy pills in `EventCockpitDeck.tsx` so `rotatePin` can dynamically overwrite
|
|
their `onclick` attributes.
|
|
|
|
## 3. Proposed Implementation
|
|
|
|
### Phase 1: Fix Backend Attendees Payload
|
|
|
|
1. In `server/routes/events.ts`, locate `GET /api/events/:id/attendees` (around
|
|
line 125).
|
|
2. Currently, the query selects only `slug` to do the `LIKE` match. Update this
|
|
to fetch `max_seats` and `expires_at` as well.
|
|
3. Include the event payload in the JSON response:
|
|
`return c.json({ success: true, attendees, event: { max_seats: event.max_seats, expires_at: event.expires_at } })`.
|
|
|
|
### Phase 2: Fix DOM Rotation Desync
|
|
|
|
1. In `ui/components/sessions/EventCockpitDeck.tsx`:
|
|
- Locate the Grid and Compact card copy buttons for Link and CLI.
|
|
- Add explicit IDs, for example: `id={'link-copy-' + event.id}` and
|
|
`id={'cli-copy-' + event.id}`.
|
|
2. In `ui/components/sessions/SessionsScript.tsx` (`rotatePin` function):
|
|
- Check if `data.slug` is returned (Jules updated the backend to return
|
|
`pinCode, slug, link, cli`).
|
|
- If `data.slug` is present, locate the link and CLI copy elements and
|
|
overwrite their `onclick` handlers dynamically so they copy the fresh
|
|
credentials.
|
|
- E.g.,
|
|
`linkElem.setAttribute('onclick', "copyText(window.location.origin + '/e/" + data.slug + "')");`
|
|
|
|
### Phase 3: Section Title Typo
|
|
|
|
1. In `ui/components/sessions/EventCockpitDeck.tsx` (around line 8), change
|
|
`<h2>Event Passes</h2>` to `<h2>Events</h2>`.
|
|
|
|
### Phase 4: Sticky Delegation Action Bar
|
|
|
|
1. In `ui/components/SessionsPage.tsx`, wrap the `Delegate Session` tab
|
|
selection block
|
|
(`<div style="display: flex; gap: 0.5rem; margin-bottom: 2rem;">...</div>`)
|
|
in a sticky container.
|
|
2. Example styling:
|
|
`position: sticky; top: 1rem; z-index: 50; background: var(--surface-bg); padding-top: 1rem; margin-top: -1rem; margin-bottom: 2rem;`.
|
|
3. Add a slight box-shadow or bottom border on scroll (optional polish) to
|
|
ensure the tabs float cleanly above scrolling session cards.
|
|
|
|
### Phase 5: Quality Gates
|
|
|
|
1. Run `deno fmt`, `deno task lint`, and `deno task check`.
|
|
2. Verify all `ui/ui_scripts.test.ts` pass and the DOM manipulation syntax is
|
|
correct.
|
|
3. Author a new test block in `server/tests/events.test.ts` for
|
|
`GET /api/events/:id/attendees` to assert that it successfully returns both
|
|
the `attendees` array and the `event` payload containing `max_seats` and
|
|
`expires_at`.
|