Files
zeekay 403ef005fd refactor: decomplect — Join + Status + storage hook are now independent
Three concerns were braided inside <Waitlist>:
  1. Joining (POST + form state machine)
  2. The gamified post-join view (rank + points + share + invite)
  3. Persistence (a localStorage key shape duplicated in the host page)

Pulled them apart. Each is independently useful; <Waitlist> is now a
thin composer of the three.

New surface — every piece exported

  • <WaitlistJoin waitlist baseUrl onSuccess onError ...> — pure form.
    No localStorage, no view machine. Drops a POST and notifies. Useful
    when the consumer wants a custom success page or a multi-step flow.
  • <WaitlistStatus entry waitlist baseUrl onEntryChange ...> — pure
    presentational rank + points + share + invite. Pass it any entry;
    it renders. No fetch on mount, no storage write. Useful on /me-style
    pages where the entry is server-rendered.
  • storage.ts — single owner of `hanzo-waitlist:<slug>` key shape:
      usePersistedEntry(slug)        — reactive hook (same-tab + cross-tab)
      readPersistedEntry(slug)       — sync getter (SSR-safe)
      writePersistedEntry(slug,e)    — single writer; emits a custom event
                                       so same-tab subscribers update
      clearPersistedEntry(slug)      — sign-out helper
      captureReferrerFromUrl()       — pulls inbound ?ref= for later submit
      readPendingReferrer()          — what Join reads at submit time
      entryKey(slug)                 — for consumers who need the raw key

<Waitlist> behavior is unchanged

It now: uses usePersistedEntry to know whether to render <WaitlistJoin>
or <WaitlistStatus>, calls writePersistedEntry on a successful join, and
re-fetches /status on mount when the cache says we're already in.

Demo page

apps/web/app/page.tsx dropped the inline localStorage parse and its ad-hoc
CachedJoin type. It calls usePersistedEntry(slug) — same hook the widget
uses — and the topbar pill flips reactively when the widget writes. No
prop drilling between widget and page. No duplicated key shape.

Rich Hickey nodding somewhere.
2026-06-10 14:13:39 -07:00
..