diff --git a/UX_AUDIT.md b/UX_AUDIT.md new file mode 100644 index 0000000..285de4e --- /dev/null +++ b/UX_AUDIT.md @@ -0,0 +1,109 @@ +# SkateSpots — UI/UX Audit & Fix Backlog + +Findings from a code-level audit across every area (spots/shops, lab, crews, invitations, +marketplace, stash, wallet, events, tours, calendars, messaging, community stats, profile, +contacts, near-me, rider card, settings). Each item has an evidence pointer. + +Work order = top-down, one batch per change-set, shipped through the normal pipeline +(`npm test` → boot smoke test → auto-deploy). + +--- + +## P0 — Broken flows & trust (dead controls, false claims) + +| # | Issue | Evidence | +|---|-------|----------| +| 1 | **"Claim This Shop" is a dead button** (no handler) | `SpotDetailPage.tsx:512` | +| 2 | **Tour "Contact Guide to Book"** links to `/messages?to=` which nothing reads → dead CTA | `TourDetailPage.tsx:55`; route is `/messages/:npub` | +| 3 | **Contacts "Message"** goes to the generic inbox, not the contact | `ContactsPage.tsx:75` | +| 4 | **Stash "Share via DM"** has no handler; edit/delete/list are hover-only (unreachable on touch) | `StashPage.tsx:222`, `:207` | +| 5 | **Marketplace cannot be bought**: no listing detail route; "Pay with Cashu" is a "Coming Soon" stub; every card navigates straight to a DM | `MarketplaceItemCard.tsx:133-152`, `GearSwapItemCard.tsx:165` | +| 6 | **Map marker opens the Leaflet popup AND the bottom sheet** at once | `SpotMap.tsx:1125`, `MapPage.tsx:1609/1927` | +| 7 | **Near Me on native: one denial = permanent dead end** (shows *web* browser help) | `MapPage.tsx:1726` + `:723-738` | +| 8 | **Settings deep links** `?section=follows\|language\|stash` render a blank page with no back | `SettingsPage.tsx:57-70` vs `1194-1215` | +| 9 | **Events calendar silently inherits an invisible `dateWindow` filter**; Past+Calendar opens the current (empty) month | `EventsPage.tsx:1118`, `:926-929` | +| 10 | **Crew invite accept says "membership confirmed"** even when only the founder can add the member | `CrewInviteCard.tsx:38-46` | +| 11 | **Crew "Share link"** promises a one-click invite; recipient only gets a join-request | `CrewInviteDialog.tsx:251-287` | +| 12 | **Logged-out DM / conversation are dead ends** (no LoginArea), unlike Contacts | `DirectMessagesPage.tsx:171`, `ConversationPage.tsx:152` | +| 13 | **Message send has no error feedback** | `ConversationPage.tsx:126-137` | + +## P0 — Errors masquerade as empty / 404 + +| Issue | Evidence | +|-------|----------| +| Detail pages map network errors to **NotFound** (implies deleted) | `SpotDetailPage.tsx:240`, `ShopDetailPage.tsx:188`, `CollectionDetailPage.tsx:224`, `CoachDetailPage.tsx:119`, `CrewDetailPage.tsx:245`, `EventDetailPage.tsx:272` | +| Leaderboards/pages ignore `isError` → "no content yet" | `EventsPage.tsx:814/1220/1265`, `BountyLeaderboardPage.tsx:141`, `ZapLeaderboardPage.tsx:159` | +| DM inbox error has no retry (Conversation does) | `DirectMessagesPage.tsx:278` | + +## P1 — Loading / empty-state defects + +| Issue | Evidence | +|-------|----------| +| Spot picker shows false "No spots found" while loading (also in CreateListing) | `SpotPicker.tsx:26,179`; `CreateListingPage.tsx:140-151,967` | +| Collection skeleton grid ≠ real grid → layout jump on load | `CollectionDetailPage.tsx:54` vs `:314` | +| Map view has **no empty state** when filters hide everything | `MapPage.tsx:1591-1868` | +| `EmptyState` nests `