mirror of
https://github.com/hanzoai/agency.git
synced 2026-11-02 19:13:28 +00:00
1 line
69 KiB
Plaintext
1 line
69 KiB
Plaintext
{"version":3,"file":"waitlist.cjs","names":[],"sources":["../src/storage.ts","../src/Join.tsx","../src/Share.tsx","../src/InviteFriends.tsx","../src/Status.tsx","../src/Waitlist.tsx","../src/useCountUp.ts","../src/Leaderboard.tsx","../src/Activity.tsx"],"sourcesContent":["// Single source of truth for the widget's localStorage shape.\n//\n// Both the widget and the host page may need to know \"is this visitor\n// already on the list, and what's their rank/refCode\" — owning that key\n// here keeps the contract in one place and lets consumers swap storage\n// out cleanly (e.g. to a cookie or a server-rendered prop).\n\nimport { useEffect, useState } from 'react'\n\n/** Persisted snapshot. Server is the source of truth; this is just a cache. */\nexport interface PersistedEntry {\n email: string\n rank?: number\n refCode?: string\n}\n\nconst PREFIX = 'hanzo-waitlist:'\nconst REF_KEY = 'hanzo-waitlist:ref'\n\nexport function entryKey(slug: string): string {\n return PREFIX + slug\n}\n\n/** Synchronous read (returns null on miss / parse error / SSR). */\nexport function readPersistedEntry(slug: string): PersistedEntry | null {\n if (typeof localStorage === 'undefined') return null\n try {\n const raw = localStorage.getItem(entryKey(slug))\n if (!raw) return null\n const parsed = JSON.parse(raw) as Partial<PersistedEntry>\n if (!parsed?.email) return null\n return { email: parsed.email, rank: parsed.rank, refCode: parsed.refCode }\n } catch {\n return null\n }\n}\n\nexport function writePersistedEntry(slug: string, entry: PersistedEntry): void {\n if (typeof localStorage === 'undefined') return\n try { localStorage.setItem(entryKey(slug), JSON.stringify(entry)) } catch { /* noop */ }\n // Notify same-tab subscribers — native `storage` event only fires cross-tab.\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('hanzo-waitlist:change', { detail: { slug } }))\n }\n}\n\nexport function clearPersistedEntry(slug: string): void {\n if (typeof localStorage === 'undefined') return\n try { localStorage.removeItem(entryKey(slug)) } catch { /* noop */ }\n if (typeof window !== 'undefined') {\n window.dispatchEvent(new CustomEvent('hanzo-waitlist:change', { detail: { slug } }))\n }\n}\n\n/** Capture an inbound ?ref=<code> URL param for later submission. */\nexport function captureReferrerFromUrl(): void {\n if (typeof window === 'undefined') return\n try {\n const ref = new URLSearchParams(window.location.search).get('ref')\n if (ref) localStorage.setItem(REF_KEY, ref)\n } catch { /* noop */ }\n}\n\nexport function readPendingReferrer(): string | undefined {\n if (typeof localStorage === 'undefined') return undefined\n try { return localStorage.getItem(REF_KEY) ?? undefined } catch { return undefined }\n}\n\n/**\n * React hook: subscribes to the persisted entry for `slug`. Reactive to\n * same-tab writes (via custom event) and cross-tab writes (via native\n * `storage` event).\n */\nexport function usePersistedEntry(slug: string): PersistedEntry | null {\n const [entry, setEntry] = useState<PersistedEntry | null>(() => readPersistedEntry(slug))\n\n useEffect(() => {\n setEntry(readPersistedEntry(slug))\n const onChange = (e: Event) => {\n const target = (e as CustomEvent<{ slug?: string }>).detail?.slug\n if (target && target !== slug) return\n setEntry(readPersistedEntry(slug))\n }\n const onStorage = (e: StorageEvent) => {\n if (e.key === entryKey(slug)) setEntry(readPersistedEntry(slug))\n }\n window.addEventListener('hanzo-waitlist:change', onChange)\n window.addEventListener('storage', onStorage)\n return () => {\n window.removeEventListener('hanzo-waitlist:change', onChange)\n window.removeEventListener('storage', onStorage)\n }\n }, [slug])\n\n return entry\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport { WaitlistClient, type WaitlistEntry } from './client'\nimport { readPendingReferrer } from './storage'\n\nexport interface WaitlistJoinProps {\n /** Slug or id of the waitlist. */\n waitlist: string\n /** Base server URL. Defaults to current origin. */\n baseUrl?: string\n /** Copy. */\n title?: string\n subtitle?: string\n submitLabel?: string\n /** Cloudflare Turnstile token, if Turnstile is enabled server-side. */\n turnstileToken?: string\n /** Pre-fill the email field. */\n email?: string\n /** Fires with the new entry after a successful POST /join. */\n onSuccess?: (entry: WaitlistEntry) => void\n /** Fires on validation OR server error. */\n onError?: (err: { message: string; status: number }) => void\n}\n\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n\n/**\n * Pure join form. No localStorage, no success view — that's the composer's\n * job (see <Waitlist>). Drops a single POST /v1/waitlist/join and notifies\n * onSuccess/onError. Pre-fills the referrerCode from storage if present.\n */\nexport function WaitlistJoin(props: WaitlistJoinProps) {\n const {\n waitlist, baseUrl,\n title = 'Join the waitlist',\n subtitle,\n submitLabel = 'Join',\n turnstileToken,\n email: initialEmail,\n onSuccess, onError,\n } = props\n\n const client = useMemo(() => new WaitlistClient({ baseUrl }), [baseUrl])\n const [email, setEmail] = useState(initialEmail ?? '')\n const [busy, setBusy] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n const submit = useCallback(async (e?: React.FormEvent) => {\n e?.preventDefault()\n if (busy) return\n const normalized = email.trim().toLowerCase()\n if (!EMAIL_RE.test(normalized)) {\n const msg = 'Enter a valid email address.'\n setError(msg)\n onError?.({ message: msg, status: 0 })\n return\n }\n\n setBusy(true)\n setError(null)\n const res = await client.join({\n waitlist,\n email: normalized,\n referrerCode: readPendingReferrer(),\n turnstileToken,\n })\n\n if ('ok' in res && res.ok) {\n setBusy(false)\n onSuccess?.(res)\n return\n }\n const message = res.message || 'Something went wrong. Try again.'\n setError(message)\n onError?.({ message, status: res.status })\n setBusy(false)\n }, [busy, client, email, onError, onSuccess, turnstileToken, waitlist])\n\n return (\n <form onSubmit={submit} noValidate>\n <h3 className=\"hanzo-waitlist__title\">{title}</h3>\n {subtitle && <p className=\"hanzo-waitlist__subtitle\">{subtitle}</p>}\n <div className=\"hanzo-waitlist__row\">\n <input\n className=\"hanzo-waitlist__input\"\n type=\"email\"\n inputMode=\"email\"\n autoComplete=\"email\"\n placeholder=\"[email protected]\"\n value={email}\n onChange={(e) => setEmail(e.currentTarget.value)}\n disabled={busy}\n aria-label=\"Email address\"\n required\n />\n <button type=\"submit\" className=\"hanzo-waitlist__button\" disabled={busy || !email}>\n {busy ? '…' : submitLabel}\n </button>\n </div>\n {error && <p className=\"hanzo-waitlist__error\" role=\"alert\">{error}</p>}\n </form>\n )\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport { WaitlistClient, type PointValues } from './client'\n\nexport type SharePlatformId =\n | 'webshare' | 'email' | 'x' | 'linkedin' | 'facebook'\n | 'reddit' | 'telegram' | 'whatsapp' | 'sms' | 'copy'\n\nexport interface ShareTarget {\n id: SharePlatformId | string\n label: string\n /** Points awarded for this action. If undefined, falls back to pointValues.SHARE. */\n points?: number\n /**\n * Returns a URL to open, OR `null` to skip the navigation (e.g. for copy /\n * webshare which do their own thing in `onClick`).\n */\n href: (ctx: ShareContext) => string | null\n /** Optional custom click handler — runs INSTEAD of href navigation. */\n onClick?: (ctx: ShareContext) => void | Promise<void>\n}\n\nexport interface ShareContext {\n url: string\n text: string\n rank: number\n refCode: string\n}\n\nexport interface WaitlistShareProps {\n /** Slug of the waitlist (needed for track-share calls). */\n waitlist: string\n /** The viewer's referral code (server credits points to this code). */\n refCode: string\n /** Full share URL (typically the host page with `?ref=<code>` appended). */\n shareUrl: string\n /** Optional viewer rank — used in default share text. */\n rank?: number\n /** Optional total — used in default share text. */\n total?: number\n\n /**\n * Override the share message. Receives the same ctx as href functions.\n * Default: `I'm #N on the waitlist. Join me:`\n */\n message?: (ctx: ShareContext) => string\n\n /**\n * Restrict / reorder targets. Pass an array of platform IDs from the\n * built-in set, OR a full ShareTarget for custom platforms. Defaults to\n * the full built-in roster.\n */\n shareTargets?: Array<SharePlatformId | ShareTarget>\n\n /**\n * Override the server's published point values for display only. The\n * actual point award still happens server-side per pointValues; this is\n * for showing custom labels.\n */\n pointValues?: Partial<PointValues>\n\n /** Base server URL. Defaults to current origin. */\n baseUrl?: string\n\n /** Callback after a successful track-share (or copy). */\n onShared?: (platform: string, awarded: number, alreadyClaimed: boolean) => void\n}\n\nconst DEFAULT_ORDER: SharePlatformId[] = [\n 'webshare', 'email', 'x', 'linkedin', 'facebook',\n 'reddit', 'telegram', 'whatsapp', 'sms', 'copy',\n]\n\nconst BUILTIN: Record<SharePlatformId, Omit<ShareTarget, 'id'>> = {\n webshare: {\n label: 'Share',\n href: () => null,\n onClick: async ({ url, text }) => {\n if (typeof navigator !== 'undefined' && 'share' in navigator) {\n try { await (navigator as Navigator & { share: (d: ShareData) => Promise<void> }).share({ text, url }) } catch { /* user cancelled */ }\n }\n },\n },\n email: {\n label: 'Email',\n href: ({ url, text }) => `mailto:?subject=${encodeURIComponent('Join the waitlist')}&body=${encodeURIComponent(`${text}\\n\\n${url}`)}`,\n },\n x: {\n label: 'X',\n href: ({ url, text }) => `https://x.com/intent/post?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`,\n },\n linkedin: {\n label: 'LinkedIn',\n href: ({ url }) => `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`,\n },\n facebook: {\n label: 'Facebook',\n href: ({ url }) => `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`,\n },\n reddit: {\n label: 'Reddit',\n href: ({ url, text }) => `https://reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent(text)}`,\n },\n telegram: {\n label: 'Telegram',\n href: ({ url, text }) => `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`,\n },\n whatsapp: {\n label: 'WhatsApp',\n href: ({ url, text }) => `https://wa.me/?text=${encodeURIComponent(`${text} ${url}`)}`,\n },\n sms: {\n label: 'SMS',\n href: ({ url, text }) => `sms:?&body=${encodeURIComponent(`${text} ${url}`)}`,\n },\n copy: {\n label: 'Copy link',\n href: () => null,\n onClick: async ({ url }) => {\n if (typeof navigator !== 'undefined' && navigator.clipboard) {\n try { await navigator.clipboard.writeText(url) } catch { /* noop */ }\n }\n },\n },\n}\n\nfunction resolveTargets(spec: WaitlistShareProps['shareTargets']): ShareTarget[] {\n const list = spec ?? DEFAULT_ORDER\n return list\n .map((entry) => {\n if (typeof entry === 'string') {\n const builtin = BUILTIN[entry as SharePlatformId]\n if (!builtin) return null\n return { id: entry, ...builtin }\n }\n return entry\n })\n .filter((x): x is ShareTarget => Boolean(x))\n}\n\nexport function WaitlistShare(props: WaitlistShareProps) {\n const {\n waitlist, refCode, shareUrl, rank = 0, total: _total,\n message, shareTargets, pointValues, baseUrl, onShared,\n } = props\n\n const client = useMemo(() => new WaitlistClient({ baseUrl }), [baseUrl])\n const targets = useMemo(() => resolveTargets(shareTargets), [shareTargets])\n const [busy, setBusy] = useState<string | null>(null)\n const [toast, setToast] = useState<string | null>(null)\n\n const sharePoints = pointValues?.SHARE ?? 2\n\n const ctx: ShareContext = useMemo(() => {\n const text = message\n ? message({ url: shareUrl, text: '', rank, refCode })\n : (rank ? `I'm #${rank.toLocaleString()} on the waitlist. Climb with me:` : 'Join me on the waitlist:')\n return { url: shareUrl, text, rank, refCode }\n }, [message, rank, refCode, shareUrl])\n\n // Hide Web Share when the API isn't there.\n const visibleTargets = useMemo(() => {\n if (typeof navigator === 'undefined' || !('share' in navigator)) {\n return targets.filter((t) => t.id !== 'webshare')\n }\n return targets\n }, [targets])\n\n const fire = useCallback(async (t: ShareTarget) => {\n if (busy) return\n setBusy(String(t.id))\n setToast(null)\n\n // Side action (copy / webshare) first so the user gets immediate feedback.\n try {\n if (t.onClick) await t.onClick(ctx)\n } catch { /* swallow — UX over correctness here */ }\n\n // Open the share URL (if any) in a new tab. Mailto/sms use same window.\n const href = t.href(ctx)\n if (href) {\n const sameWindow = href.startsWith('mailto:') || href.startsWith('sms:')\n if (sameWindow) {\n window.location.href = href\n } else {\n window.open(href, '_blank', 'noopener,noreferrer')\n }\n }\n\n // Fire-and-forget point award. Caps and dedup live on the server.\n const result = await client.trackShare({ waitlist, refCode, platform: String(t.id) })\n let awarded = 0\n let alreadyClaimed = false\n if ('ok' in result && result.ok) {\n awarded = result.awarded\n alreadyClaimed = result.alreadyClaimed\n if (awarded > 0) setToast(`+${awarded} from ${t.label}`)\n else if (alreadyClaimed) setToast(`Already counted today`)\n }\n onShared?.(String(t.id), awarded, alreadyClaimed)\n\n setBusy(null)\n // Auto-clear toast.\n setTimeout(() => setToast(null), 2200)\n }, [busy, client, ctx, onShared, refCode, waitlist])\n\n return (\n <div className=\"hanzo-waitlist__share-wrap\">\n <ul className=\"hanzo-waitlist__share\" role=\"list\">\n {visibleTargets.map((t) => {\n const pts = t.points ?? sharePoints\n const isBusy = busy === String(t.id)\n const emphasized = t.id === 'webshare' || t.id === 'copy'\n return (\n <li key={String(t.id)}>\n <button\n type=\"button\"\n className={`hanzo-waitlist__share-btn${emphasized ? '' : ' hanzo-waitlist__button--ghost'}`}\n onClick={() => fire(t)}\n disabled={isBusy}\n aria-label={`${t.label} (+${pts})`}\n >\n <span className=\"hanzo-waitlist__share-label\">{t.label}</span>\n {pts > 0 && (\n <span className=\"hanzo-waitlist__share-pts\" aria-hidden=\"true\">+{pts}</span>\n )}\n </button>\n </li>\n )\n })}\n </ul>\n <div className=\"hanzo-waitlist__toast\" role=\"status\" aria-live=\"polite\">\n {toast}\n </div>\n </div>\n )\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport { WaitlistClient, type InviteResponse } from './client'\n\nexport interface WaitlistInviteFriendsProps {\n /** Waitlist slug. */\n waitlist: string\n /** Viewer's referral code (server credits the points here). */\n refCode: string\n /** Base server URL. */\n baseUrl?: string\n /** Points per invite-sent, for display. Server is the source of truth. */\n pointPerInvite?: number\n /** Points per converted invite (when invited friend joins). */\n pointPerConversion?: number\n /** Max emails per submit (default 50). */\n maxBatch?: number\n /** Initial message body (optional, sent to the server). */\n defaultMessage?: string\n /** Callback after a successful submit. */\n onSent?: (result: InviteResponse) => void\n}\n\nfunction parseEmails(input: string): string[] {\n return input\n .split(/[\\s,;]+/)\n .map((s) => s.trim())\n .filter(Boolean)\n}\n\nexport function WaitlistInviteFriends(props: WaitlistInviteFriendsProps) {\n const {\n waitlist, refCode, baseUrl,\n pointPerInvite = 1,\n pointPerConversion = 5,\n maxBatch = 50,\n defaultMessage = '',\n onSent,\n } = props\n\n const client = useMemo(() => new WaitlistClient({ baseUrl }), [baseUrl])\n const [open, setOpen] = useState(false)\n const [raw, setRaw] = useState('')\n const [message, setMessage] = useState(defaultMessage)\n const [busy, setBusy] = useState(false)\n const [result, setResult] = useState<InviteResponse | null>(null)\n const [error, setError] = useState<string | null>(null)\n\n const emails = useMemo(() => parseEmails(raw), [raw])\n const count = emails.length\n const over = count > maxBatch\n const potential = count * pointPerInvite\n\n const submit = useCallback(async () => {\n if (count === 0 || over || busy) return\n setBusy(true)\n setError(null)\n setResult(null)\n const res = await client.invite({ waitlist, refCode, emails, message: message || undefined })\n if ('ok' in res && res.ok) {\n setResult(res)\n setRaw('')\n onSent?.(res)\n } else {\n setError(res.message || 'failed to send')\n }\n setBusy(false)\n }, [busy, client, count, emails, message, onSent, over, refCode, waitlist])\n\n return (\n <div className=\"hanzo-waitlist__invite\">\n <button\n type=\"button\"\n className=\"hanzo-waitlist__invite-toggle\"\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n >\n <span>Invite friends</span>\n <span className=\"hanzo-waitlist__invite-toggle-meta\">\n +{pointPerInvite}/sent · +{pointPerConversion}/joined\n </span>\n <span aria-hidden=\"true\" className={`hanzo-waitlist__chev${open ? ' is-open' : ''}`}>›</span>\n </button>\n\n {open && (\n <div className=\"hanzo-waitlist__invite-panel\">\n <label className=\"hanzo-waitlist__invite-label\" htmlFor=\"hw-invite-emails\">\n Emails\n <span className=\"hanzo-waitlist__invite-hint\">\n {count} {count === 1 ? 'address' : 'addresses'}\n {over && ` — max ${maxBatch}`}\n {!over && count > 0 && ` · +${potential} pts pending`}\n </span>\n </label>\n <textarea\n id=\"hw-invite-emails\"\n className=\"hanzo-waitlist__invite-textarea\"\n placeholder={`[email protected]\\[email protected], [email protected]`}\n rows={4}\n value={raw}\n onChange={(e) => setRaw(e.currentTarget.value)}\n disabled={busy}\n />\n <input\n type=\"text\"\n className=\"hanzo-waitlist__input\"\n placeholder=\"Personal note (optional)\"\n value={message}\n maxLength={500}\n onChange={(e) => setMessage(e.currentTarget.value)}\n disabled={busy}\n />\n <button\n type=\"button\"\n className=\"hanzo-waitlist__button\"\n onClick={submit}\n disabled={busy || count === 0 || over}\n >\n {busy ? 'Sending…' : count > 0 ? `Send ${count} ${count === 1 ? 'invite' : 'invites'}` : 'Send invites'}\n </button>\n\n {error && <p className=\"hanzo-waitlist__error\" role=\"alert\">{error}</p>}\n {result && (\n <p className=\"hanzo-waitlist__invite-result\" role=\"status\">\n Sent <strong>{result.sent}</strong>\n {result.skipped > 0 && <>, skipped {result.skipped} <small>(already on list)</small></>}\n {result.invalid > 0 && <>, {result.invalid} invalid</>}\n {result.duplicates > 0 && <>, {result.duplicates} duplicates</>}\n {result.pointsAwarded > 0 && <> · +{result.pointsAwarded} pts</>}\n </p>\n )}\n </div>\n )}\n </div>\n )\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport type { WaitlistEntry } from './client'\nimport { WaitlistShare, type SharePlatformId, type ShareTarget } from './Share'\nimport { WaitlistInviteFriends } from './InviteFriends'\n\nexport interface WaitlistStatusProps {\n /** The entry to render. Server is the source of truth; this is just the view. */\n entry: WaitlistEntry\n /** Waitlist slug — needed for share + invite POSTs. */\n waitlist: string\n /** Base server URL. Defaults to current origin. */\n baseUrl?: string\n\n /** Override the \"You're on the list\" headline. */\n title?: string\n /** Override the subtitle line under the rank. */\n subtitle?: (entry: WaitlistEntry) => string\n\n /** Hide the share grid. */\n hideShare?: boolean\n /** Hide the invite-friends panel. */\n hideInvite?: boolean\n /** Hide the points score block. */\n hidePoints?: boolean\n /** Restrict / reorder share platforms. */\n shareTargets?: Array<SharePlatformId | ShareTarget>\n\n /**\n * Called whenever the user earns points locally (share click, invite send)\n * so consumers can keep external caches in sync. Receives the updated entry.\n */\n onEntryChange?: (next: WaitlistEntry) => void\n}\n\nconst defaultSubtitle = (e: WaitlistEntry) =>\n e.aheadOf && e.aheadOf > 0\n ? `${e.aheadOf.toLocaleString()} ${e.aheadOf === 1 ? 'person is' : 'people are'} behind you. Refer friends to climb.`\n : 'Refer friends to climb the list.'\n\n/**\n * Presentational gamified post-join view: rank, points breakdown, share grid,\n * invite panel. State-light by design — pass it an entry, render the entry,\n * notify the caller on local point gains. No network on mount, no localStorage.\n */\nexport function WaitlistStatus(props: WaitlistStatusProps) {\n const {\n entry, waitlist, baseUrl,\n title = \"You're on the list\",\n subtitle = defaultSubtitle,\n hideShare, hideInvite, hidePoints, shareTargets,\n onEntryChange,\n } = props\n\n // Local mirror so we can optimistically reflect share/invite point gains\n // even when the caller doesn't pass onEntryChange. The server is still the\n // source of truth — caller can blow this away with a fresh entry whenever.\n const [local, setLocal] = useState<WaitlistEntry>(entry)\n // Reset local to upstream whenever a new entry is passed.\n if (entry !== local && entry.email === local.email && entry.points !== local.points) {\n setLocal(entry)\n }\n\n const view = entry === local || entry.points >= local.points ? entry : local\n\n const shareUrl = useMemo(() => {\n if (typeof window === 'undefined') return view.shareUrl\n const u = new URL(window.location.href)\n u.search = ''\n u.searchParams.set('ref', view.refCode)\n return u.toString()\n }, [view.refCode, view.shareUrl])\n\n const bump = useCallback((points: number, breakdown: WaitlistEntry['pointBreakdown']) => {\n const next = { ...view, points, pointBreakdown: breakdown }\n setLocal(next)\n onEntryChange?.(next)\n }, [onEntryChange, view])\n\n const pb = view.pointBreakdown\n const pv = view.pointValues\n\n return (\n <div className=\"hanzo-waitlist__success\">\n <h3 className=\"hanzo-waitlist__title\" style={{ textAlign: 'center' }}>{title}</h3>\n <div className=\"hanzo-waitlist__rank\" aria-label={`Rank ${view.rank} of ${view.total}`}>\n {view.rank.toLocaleString()}\n </div>\n <p className=\"hanzo-waitlist__of\" aria-hidden=\"true\">of {view.total.toLocaleString()}</p>\n <p className=\"hanzo-waitlist__meta\">{subtitle(view)}</p>\n\n {!hidePoints && (\n <div className=\"hanzo-waitlist__score\" aria-label={`${view.points} points`}>\n <div className=\"hanzo-waitlist__score-num\">\n {view.points.toLocaleString()}\n <span className=\"hanzo-waitlist__score-suffix\">pts</span>\n </div>\n <ul className=\"hanzo-waitlist__score-breakdown\" role=\"list\">\n <li><b>{pb.referrals}</b> referrals <small>×{pv.REFERRAL}</small></li>\n <li><b>{pb.shares}</b> shares <small>×{pv.SHARE}</small></li>\n <li><b>{pb.invitesSent}</b> invites <small>×{pv.INVITE_SENT}</small></li>\n <li><b>{pb.invitesConverted}</b> joined <small>×{pv.INVITE_CONVERTED}</small></li>\n </ul>\n </div>\n )}\n\n {!hideShare && (\n <WaitlistShare\n waitlist={waitlist}\n refCode={view.refCode}\n shareUrl={shareUrl}\n rank={view.rank}\n total={view.total}\n baseUrl={baseUrl}\n shareTargets={shareTargets}\n pointValues={view.pointValues}\n onShared={(_platform, awarded) => {\n if (awarded > 0) bump(view.points + awarded, { ...pb, shares: pb.shares + awarded })\n }}\n />\n )}\n\n {!hideInvite && (\n <WaitlistInviteFriends\n waitlist={waitlist}\n refCode={view.refCode}\n baseUrl={baseUrl}\n pointPerInvite={pv.INVITE_SENT}\n pointPerConversion={pv.INVITE_CONVERTED}\n onSent={(r) => bump(view.points + r.pointsAwarded, { ...pb, invitesSent: pb.invitesSent + r.pointsAwarded })}\n />\n )}\n </div>\n )\n}\n","// Top-level convenience component composing the join flow.\n//\n// Composition layout — each piece is independently usable, see ./Join,\n// ./Status, ./Share, ./InviteFriends:\n//\n// <Waitlist>\n// <Card>\n// {entry ? <WaitlistStatus/> : <WaitlistJoin/>}\n// </Card>\n//\n// State management is delegated to storage.usePersistedEntry — the same\n// hook the host page uses to drive its sticky CTA. One source of truth.\n\nimport { useCallback, useEffect, useMemo, useState } from 'react'\nimport { WaitlistClient, type WaitlistEntry } from './client'\nimport { WaitlistJoin, type WaitlistJoinProps } from './Join'\nimport { WaitlistStatus } from './Status'\nimport { captureReferrerFromUrl, usePersistedEntry, writePersistedEntry } from './storage'\nimport type { SharePlatformId, ShareTarget } from './Share'\n\nexport type WaitlistMode = 'inline' | 'modal'\nexport type WaitlistTheme = 'auto' | 'light' | 'dark'\n\nexport interface WaitlistProps {\n /** Slug or id of the waitlist on the Base server. */\n waitlist: string\n /** Where the Base server lives. Defaults to current origin. */\n baseUrl?: string\n /** Layout: `inline` renders the form in place, `modal` renders a button that opens it. */\n mode?: WaitlistMode\n /** Light / dark / `auto` (follow OS). */\n theme?: WaitlistTheme\n /** Consumer-provided logo (rendered above the title in both Join and Status). */\n logo?: React.ReactNode\n\n /** Join form copy + Turnstile token. */\n title?: WaitlistJoinProps['title']\n subtitle?: WaitlistJoinProps['subtitle']\n submitLabel?: WaitlistJoinProps['submitLabel']\n turnstileToken?: WaitlistJoinProps['turnstileToken']\n\n /** Status view copy. */\n successTitle?: string\n successSubtitle?: (entry: WaitlistEntry) => string\n\n /** Optional CTA before user submits (modal mode). */\n triggerLabel?: string\n\n /** Toggle pieces of the status view. */\n hideShare?: boolean\n hideInvite?: boolean\n hidePoints?: boolean\n shareTargets?: Array<SharePlatformId | ShareTarget>\n\n /** Forward to root container. */\n className?: string\n style?: React.CSSProperties\n\n /** Callbacks. */\n onSuccess?: (entry: WaitlistEntry) => void\n onError?: WaitlistJoinProps['onError']\n}\n\nexport function Waitlist(props: WaitlistProps) {\n const {\n waitlist, baseUrl,\n mode = 'inline',\n theme = 'auto',\n logo,\n title, subtitle, submitLabel, turnstileToken,\n successTitle, successSubtitle,\n triggerLabel = 'Join waitlist',\n hideShare, hideInvite, hidePoints, shareTargets,\n className, style,\n onSuccess, onError,\n } = props\n\n const client = useMemo(() => new WaitlistClient({ baseUrl }), [baseUrl])\n const cached = usePersistedEntry(waitlist)\n const [entry, setEntry] = useState<WaitlistEntry | null>(null)\n const [modalOpen, setModalOpen] = useState(false)\n\n // On mount: capture inbound ?ref= URL and rehydrate the cached entry.\n useEffect(() => { captureReferrerFromUrl() }, [])\n\n useEffect(() => {\n if (!cached?.email) { setEntry(null); return }\n let cancelled = false\n client.status({ waitlist, email: cached.email }).then((res) => {\n if (cancelled) return\n if ('ok' in res && res.ok) setEntry(res)\n })\n return () => { cancelled = true }\n }, [cached?.email, client, waitlist])\n\n const handleSuccess = useCallback((next: WaitlistEntry) => {\n writePersistedEntry(waitlist, { email: next.email, rank: next.rank, refCode: next.refCode })\n setEntry(next)\n onSuccess?.(next)\n }, [onSuccess, waitlist])\n\n const card = (\n <Card theme={theme} className={className} style={style}>\n {logo && <div className=\"hanzo-waitlist__logo\">{logo}</div>}\n {entry ? (\n <WaitlistStatus\n entry={entry}\n waitlist={waitlist}\n baseUrl={baseUrl}\n title={successTitle}\n subtitle={successSubtitle}\n hideShare={hideShare}\n hideInvite={hideInvite}\n hidePoints={hidePoints}\n shareTargets={shareTargets}\n onEntryChange={setEntry}\n />\n ) : (\n <WaitlistJoin\n waitlist={waitlist}\n baseUrl={baseUrl}\n title={title}\n subtitle={subtitle}\n submitLabel={submitLabel}\n turnstileToken={turnstileToken}\n onSuccess={handleSuccess}\n onError={onError}\n />\n )}\n </Card>\n )\n\n if (mode === 'inline') return card\n\n return (\n <>\n <button\n type=\"button\"\n className=\"hanzo-waitlist__trigger\"\n onClick={() => setModalOpen(true)}\n >\n {entry ? `#${entry.rank.toLocaleString()} — view` : triggerLabel}\n </button>\n {modalOpen && (\n <div\n className=\"hanzo-waitlist__backdrop\"\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(e) => { if (e.target === e.currentTarget) setModalOpen(false) }}\n >\n <div className=\"hanzo-waitlist__dialog\">{card}</div>\n </div>\n )}\n </>\n )\n}\n\nfunction Card(p: { theme: WaitlistTheme; className?: string; style?: React.CSSProperties; children: React.ReactNode }) {\n const themeAttr = p.theme === 'auto' ? undefined : p.theme\n const className = ['hanzo-waitlist', p.className].filter(Boolean).join(' ')\n return (\n <div className={className} data-theme={themeAttr} style={p.style}>\n <div className=\"hanzo-waitlist__card\">{p.children}</div>\n </div>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\n\nexport interface UseCountUpOptions {\n /** Animation duration in ms. Default 1200. Set 0 to disable. */\n duration?: number\n /** Easing function. Default cubic ease-out. */\n ease?: (t: number) => number\n /** Re-trigger on `target` changes. Default true. */\n retrigger?: boolean\n}\n\nconst easeOutCubic = (t: number) => 1 - Math.pow(1 - t, 3)\n\n/**\n * Smoothly animates from 0 (or the previous value) up to `target`. Honors\n * `prefers-reduced-motion` and a `duration: 0` opt-out.\n */\nexport function useCountUp(target: number | null, opts: UseCountUpOptions = {}): number {\n const {\n duration = 1200,\n ease = easeOutCubic,\n retrigger = true,\n } = opts\n\n const [value, setValue] = useState(0)\n const raf = useRef<number | null>(null)\n const prev = useRef(0)\n\n useEffect(() => {\n if (target === null || target === undefined) return\n if (duration <= 0) { setValue(target); prev.current = target; return }\n\n const reduce = typeof window !== 'undefined' && window.matchMedia?.('(prefers-reduced-motion: reduce)').matches\n if (reduce) { setValue(target); prev.current = target; return }\n\n const from = retrigger ? prev.current : value\n const to = target\n if (from === to) return\n\n const start = performance.now()\n const step = (now: number) => {\n const t = Math.min(1, (now - start) / duration)\n const v = from + (to - from) * ease(t)\n setValue(Math.round(v))\n if (t < 1) raf.current = requestAnimationFrame(step)\n else { prev.current = to; raf.current = null }\n }\n raf.current = requestAnimationFrame(step)\n return () => { if (raf.current) cancelAnimationFrame(raf.current) }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [target, duration])\n\n return value\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react'\nimport { WaitlistClient, type LeaderboardEntry } from './client'\nimport { useCountUp } from './useCountUp'\n\nexport type LeaderboardMode = 'load-more' | 'paginate'\n\nexport interface WaitlistLeaderboardProps {\n /** Slug or id of the waitlist. */\n waitlist: string\n /** Base server URL. Defaults to current origin. */\n baseUrl?: string\n /** Entries per page. Default 25. */\n pageSize?: number\n /** Theme override ('auto' | 'light' | 'dark'). */\n theme?: 'auto' | 'light' | 'dark'\n /**\n * Highlight the row matching this email (typically the current viewer).\n * The widget's `Waitlist` component stores the joined email in\n * localStorage under `hanzo-waitlist:<slug>` — read it there to wire up.\n */\n highlightEmail?: string\n /**\n * `'load-more'` (default) — single button at the bottom that appends the\n * next chunk; no page counters or arrows.\n * `'paginate'` — classic next/prev with a page count.\n */\n mode?: LeaderboardMode\n /** Override the load-more button text. */\n loadMoreLabel?: string\n /** Text shown after the last page in load-more mode. Set to '' to hide. */\n exhaustedLabel?: string\n /**\n * Animated count-up on the total (\"1,205 on the list\"). Pass `false`\n * to disable, or an object to tune the duration. Default true / 1200ms.\n */\n animateTotal?: boolean | { duration?: number }\n /** Optional className on the root container. */\n className?: string\n style?: React.CSSProperties\n /**\n * Custom renderer for the \"email\" cell. Default shows the masked email.\n * Use this to render avatars, social links, etc.\n */\n renderEmail?: (entry: LeaderboardEntry) => React.ReactNode\n}\n\n/**\n * Paginated leaderboard view of a waitlist. The widget itself stays per-user\n * (Join + your-rank); this is the public list view. Same monochrome surface,\n * same CSS variables, same brand-neutral design — drop in next to <Waitlist>.\n */\nexport function WaitlistLeaderboard(props: WaitlistLeaderboardProps) {\n const {\n waitlist,\n baseUrl,\n pageSize = 25,\n theme = 'auto',\n highlightEmail,\n mode = 'load-more',\n loadMoreLabel = 'Show more',\n exhaustedLabel = \"That's everyone\",\n animateTotal = true,\n className,\n style,\n renderEmail,\n } = props\n\n const client = useMemo(() => new WaitlistClient({ baseUrl }), [baseUrl])\n const [page, setPage] = useState(1)\n const [entries, setEntries] = useState<LeaderboardEntry[]>([])\n const [meta, setMeta] = useState<{ total: number; totalPages: number } | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [busy, setBusy] = useState(false)\n\n // For load-more, accumulate; for paginate, replace.\n const load = useCallback(async (p: number, append: boolean) => {\n setBusy(true)\n setError(null)\n const res = await client.list({ waitlist, page: p, pageSize })\n if ('ok' in res && res.ok) {\n setMeta({ total: res.total, totalPages: res.totalPages })\n setEntries((prev) => {\n if (!append) return res.entries\n // Dedup by rank in case of overlapping fetches.\n const seen = new Set(prev.map((e) => e.rank))\n const fresh = res.entries.filter((e) => !seen.has(e.rank))\n return [...prev, ...fresh]\n })\n } else {\n setError(res.message || 'failed to load')\n }\n setBusy(false)\n }, [client, pageSize, waitlist])\n\n // Initial load and whenever waitlist/pageSize change.\n useEffect(() => {\n setPage(1)\n setEntries([])\n load(1, false)\n }, [load])\n\n const total = meta?.total ?? 0\n const animDuration = animateTotal === false ? 0 : (typeof animateTotal === 'object' ? animateTotal.duration ?? 1200 : 1200)\n const animatedTotal = useCountUp(meta ? total : null, { duration: animDuration })\n const displayedTotal = animateTotal === false ? total : animatedTotal\n const isPaginate = mode === 'paginate'\n const isLastPage = meta ? page >= meta.totalPages : false\n const isExhausted = mode === 'load-more' && meta && entries.length >= meta.total\n\n const onLoadMore = useCallback(() => {\n if (busy) return\n const next = page + 1\n setPage(next)\n load(next, true)\n }, [busy, load, page])\n\n const themeAttr = theme === 'auto' ? undefined : theme\n\n return (\n <div className={['hanzo-waitlist', className].filter(Boolean).join(' ')} data-theme={themeAttr} style={style}>\n <div className=\"hanzo-waitlist__card hanzo-waitlist-lb\">\n <header className=\"hanzo-waitlist-lb__head\">\n <div>\n <h3 className=\"hanzo-waitlist__title\">Leaderboard</h3>\n <p className=\"hanzo-waitlist__subtitle\">\n <span className=\"hanzo-waitlist-lb__total\">{displayedTotal.toLocaleString()}</span> on the list\n </p>\n </div>\n {isPaginate && (\n <Pager\n page={page}\n totalPages={meta?.totalPages ?? 1}\n busy={busy}\n onChange={(p) => { setPage(p); load(p, false) }}\n />\n )}\n </header>\n\n {error && <p className=\"hanzo-waitlist__error\" role=\"alert\">{error}</p>}\n\n <ol className=\"hanzo-waitlist-lb__list\">\n {entries.map((e) => {\n const mine = highlightEmail && e.email.toLowerCase() === highlightEmail.toLowerCase()\n return (\n <li\n key={`${e.rank}-${e.email}`}\n className=\"hanzo-waitlist-lb__row\"\n data-mine={mine ? 'true' : undefined}\n >\n <span className=\"hanzo-waitlist-lb__rank\">#{e.rank.toLocaleString()}</span>\n <span className=\"hanzo-waitlist-lb__email\">\n {renderEmail ? renderEmail(e) : e.email}\n </span>\n <span className=\"hanzo-waitlist-lb__refs\" aria-label={`${e.referralCount} referrals`}>\n {e.referralCount.toLocaleString()}\n </span>\n </li>\n )\n })}\n {!error && entries.length === 0 && (\n <li className=\"hanzo-waitlist-lb__empty\">\n {busy ? 'Loading…' : 'No one yet — be the first.'}\n </li>\n )}\n </ol>\n\n {!isPaginate && meta && !isExhausted && (\n <footer className=\"hanzo-waitlist-lb__foot\">\n <button\n type=\"button\"\n className=\"hanzo-waitlist__button hanzo-waitlist__button--ghost hanzo-waitlist-lb__more\"\n onClick={onLoadMore}\n disabled={busy}\n >\n {busy ? 'Loading…' : loadMoreLabel}\n </button>\n </footer>\n )}\n {!isPaginate && isExhausted && exhaustedLabel && (\n <footer className=\"hanzo-waitlist-lb__foot\">\n <span className=\"hanzo-waitlist-lb__exhausted\">{exhaustedLabel}</span>\n </footer>\n )}\n {isPaginate && (meta?.totalPages ?? 1) > 1 && (\n <footer className=\"hanzo-waitlist-lb__foot\">\n <Pager\n page={page}\n totalPages={meta?.totalPages ?? 1}\n busy={busy}\n onChange={(p) => { setPage(p); load(p, false) }}\n />\n </footer>\n )}\n {!isPaginate && isLastPage && false /* suppress noop */}\n </div>\n </div>\n )\n}\n\nfunction Pager(p: { page: number; totalPages: number; busy: boolean; onChange: (n: number) => void }) {\n const prev = () => p.onChange(Math.max(1, p.page - 1))\n const next = () => p.onChange(Math.min(p.totalPages, p.page + 1))\n return (\n <div className=\"hanzo-waitlist-lb__pager\">\n <button\n type=\"button\"\n className=\"hanzo-waitlist__button hanzo-waitlist__button--ghost\"\n onClick={prev}\n disabled={p.busy || p.page <= 1}\n aria-label=\"Previous page\"\n >←</button>\n <span className=\"hanzo-waitlist-lb__pageinfo\">\n {p.page.toLocaleString()} / {p.totalPages.toLocaleString()}\n </span>\n <button\n type=\"button\"\n className=\"hanzo-waitlist__button hanzo-waitlist__button--ghost\"\n onClick={next}\n disabled={p.busy || p.page >= p.totalPages}\n aria-label=\"Next page\"\n >→</button>\n </div>\n )\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport {\n WaitlistClient,\n type ActivityEvent,\n type ActivityType,\n} from './client'\n\nexport type ActivityFormatter = (evt: ActivityEvent, ctx: { relative: string }) => React.ReactNode\n\nexport interface WaitlistActivityProps {\n /** Slug or id of the waitlist. */\n waitlist: string\n /** Base server URL. */\n baseUrl?: string\n /** Items to show. Default 8. */\n limit?: number\n /** Restrict to specific event types. Default: all. */\n types?: ActivityType[]\n /** Poll interval in ms. 0 = no polling (one-shot). Default 12000. */\n pollInterval?: number\n /** Theme override. */\n theme?: 'auto' | 'light' | 'dark'\n /** Override each row's content. Receives event + computed relative time. */\n formatEvent?: ActivityFormatter\n /** Custom relative-time formatter. */\n formatRelative?: (deltaMs: number) => string\n /** Show heading. Default true. */\n showHeading?: boolean\n /** Heading text. Default \"Recent activity\". */\n heading?: string\n /** Empty-state message. */\n emptyLabel?: string\n className?: string\n style?: React.CSSProperties\n}\n\nfunction defaultRelative(deltaMs: number): string {\n const s = Math.max(0, Math.floor(deltaMs / 1000))\n if (s < 30) return 'just now'\n if (s < 60) return `${s}s ago`\n const m = Math.floor(s / 60)\n if (m < 60) return `${m}m ago`\n const h = Math.floor(m / 60)\n if (h < 24) return `${h}h ago`\n const d = Math.floor(h / 24)\n if (d < 7) return `${d}d ago`\n const w = Math.floor(d / 7)\n return `${w}w ago`\n}\n\nfunction platformLabel(p?: string): string {\n if (!p) return 'somewhere'\n const m: Record<string, string> = {\n x: 'X', twitter: 'X',\n linkedin: 'LinkedIn',\n facebook: 'Facebook',\n reddit: 'Reddit',\n telegram: 'Telegram',\n whatsapp: 'WhatsApp',\n email: 'email',\n sms: 'SMS',\n copy: 'link',\n webshare: 'a friend',\n mastodon: 'Mastodon',\n bluesky: 'Bluesky',\n threads: 'Threads',\n }\n return m[p.toLowerCase()] ?? p\n}\n\nfunction defaultFormat(evt: ActivityEvent): React.ReactNode {\n switch (evt.type) {\n case 'join':\n return <><b>{evt.who}</b> joined{evt.source === 'referral' ? ' (referred)' : ''}</>\n case 'share': {\n const p = evt.platform?.toLowerCase()\n if (p === 'copy') return <><b>{evt.who}</b> copied their link</>\n if (p === 'webshare') return <><b>{evt.who}</b> shared via system</>\n if (p === 'email') return <><b>{evt.who}</b> shared by email</>\n if (p === 'sms') return <><b>{evt.who}</b> texted their link</>\n return <><b>{evt.who}</b> shared on {platformLabel(evt.platform)}</>\n }\n case 'invite':\n return <><b>{evt.who}</b> invited a friend</>\n case 'referral':\n return <><b>{evt.who}</b> earned a referral</>\n }\n}\n\nexport function WaitlistActivity(props: WaitlistActivityProps) {\n const {\n waitlist, baseUrl,\n limit = 8,\n types,\n pollInterval = 12000,\n theme = 'auto',\n formatEvent,\n formatRelative,\n showHeading = true,\n heading = 'Recent activity',\n emptyLabel = 'Quiet for now.',\n className, style,\n } = props\n\n const client = useMemo(() => new WaitlistClient({ baseUrl }), [baseUrl])\n const [events, setEvents] = useState<ActivityEvent[]>([])\n const [serverNow, setServerNow] = useState<number | null>(null)\n const [, force] = useState(0)\n const mounted = useRef(true)\n\n // Initial + polling fetch.\n useEffect(() => {\n mounted.current = true\n const fetchOnce = async () => {\n const r = await client.activity({ waitlist, limit, types })\n if (!mounted.current) return\n if ('ok' in r && r.ok) {\n setEvents(r.entries)\n setServerNow(r.now)\n }\n }\n fetchOnce()\n if (pollInterval <= 0) return undefined\n const id = window.setInterval(fetchOnce, pollInterval)\n return () => {\n mounted.current = false\n window.clearInterval(id)\n }\n }, [client, waitlist, limit, pollInterval, types])\n\n // Tick relative times even between polls so \"just now\" → \"10s ago\".\n useEffect(() => {\n const id = window.setInterval(() => force((n) => n + 1), 10000)\n return () => window.clearInterval(id)\n }, [])\n\n const themeAttr = theme === 'auto' ? undefined : theme\n\n const rel = useCallback((ts: number) => {\n const fmt = formatRelative ?? defaultRelative\n // Use server-now if we have it; the wall-clock drift is handled by\n // the difference computation.\n const base = serverNow ?? Date.now()\n const wallDrift = Date.now() - (serverNow ?? Date.now())\n return fmt(base - ts + wallDrift)\n }, [formatRelative, serverNow])\n\n return (\n <div className={['hanzo-waitlist', className].filter(Boolean).join(' ')} data-theme={themeAttr} style={style}>\n <div className=\"hanzo-waitlist__card hanzo-waitlist-act\">\n {showHeading && (\n <header className=\"hanzo-waitlist-act__head\">\n <h3 className=\"hanzo-waitlist__title\">{heading}</h3>\n <span className=\"hanzo-waitlist-act__pulse\" aria-hidden=\"true\" />\n </header>\n )}\n {events.length === 0 ? (\n <p className=\"hanzo-waitlist__hint\" style={{ textAlign: 'left' }}>{emptyLabel}</p>\n ) : (\n <ul className=\"hanzo-waitlist-act__list\" role=\"list\">\n {events.map((e, i) => {\n const relative = rel(e.ts)\n return (\n <li key={`${e.ts}-${i}`} className=\"hanzo-waitlist-act__row\">\n <span className={`hanzo-waitlist-act__dot hanzo-waitlist-act__dot--${e.type}`} aria-hidden=\"true\" />\n <span className=\"hanzo-waitlist-act__text\">\n {formatEvent ? formatEvent(e, { relative }) : defaultFormat(e)}\n </span>\n <time className=\"hanzo-waitlist-act__time\" dateTime={new Date(e.ts).toISOString()}>\n {relative}\n </time>\n </li>\n )\n })}\n </ul>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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"} |