Commit graph

266 commits

Author SHA1 Message Date
shakespeare.diy
0a47bb47d2 Fix native crash: bundle @capacitor/core instead of externalizing it
The boot crash guard surfaced the real root cause on-device:
  TypeError: Failed to resolve module specifier "@capacitor/core"

@capacitor/core and @capacitor/camera were marked `external` in the
Rollup config, which left bare `import "@capacitor/core"` specifiers in
the output bundle. A native WebView has no module resolver for bare
specifiers, so boot crashed before React mounted.

Fix: remove the INSTALLED Capacitor packages from `external` so their JS
API layer is bundled (the native implementation is still injected at
runtime via window.Capacitor). Only the four NON-installed packages
(@capacitor/app, haptics, keyboard, status-bar) stay external — they are
never statically imported (accessed via window.Capacitor.Plugins), so
this can't break the build.

Bump to 1.0.65.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 18:31:26 +07:00
shakespeare.diy
95afd9551f Bump version to 1.0.64 (native white-screen fix + boot crash guard)
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 18:22:48 +07:00
shakespeare.diy
5334144d27 Fix native white screen: relative asset base + boot crash guard
Two changes targeting the post-update white screen on the Zapstore APK:

1. vite.config: set base './' when CAPACITOR_BUILD is set. In a native
   WebView the bundle is served from the local filesystem, so absolute '/'
   asset paths are the classic cause of a silent white screen. The web
   deploy keeps '/'. This is the documented Capacitor requirement and is
   zero-risk to the working web build.

2. index.html: add a dependency-free "boot crash guard" that runs before
   the app bundle and paints any uncaught error / unhandled rejection —
   plus a 12s "did not render" timeout — directly to the screen using
   inline styles only. A boot failure that would otherwise be an
   info-less white screen now shows the actual error ON DEVICE, with no
   USB/remote-debugging needed. main.tsx signals a clean boot to cancel
   the timeout guard.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 18:21:57 +07:00
shakespeare.diy
9a8609354e Polish native-only wallet card + add Crew↔Lab scene focus
Wallet (Request A): redesign the browser CashuWalletBrowserNotice into a
premium, intentional card — gradient hero header, "App only" badge, and a
"works in your browser now" panel highlighting NWC / Alby / Lightning
address zaps. Keeps the native-only gate; no bug reintroduced.

Crew ↔ Lab interconnection: crews can now declare an optional Lab scene
focus that surfaces them inside the matching Lab category, while regular
crews stay "Mixed" and only appear on the Crews page.
- types: CrewFocus ('mixed'|'builder'|'photo'|'coaching'), labels,
  crew-focus-* t-tag scheme, serviceType→focus mapping; parseSkateCrew
  extracts focus and excludes focus tags from vibes; SkateCrew.focus field.
- CrewForm: "Crew Type" selector (Mixed / DIY & Builders / Photo & Film /
  Coaching); publishes a queryable crew-focus-* t-tag when not mixed.
- useCrews: new useCrewsByFocus hook (relay-level #t filtering).
- CrewsPage: focus badge on cards + focus filter chips.
- LabPage: "Crews in this scene" horizontal strip beneath results, mapping
  building→builder, filming/photography/editing→photo, coaching→coaching.
- NIP.md: document the crew-focus-<scene> tag.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 18:08:51 +07:00
shakespeare.diy
5cde2a640d Bump version to 1.0.63 for Zapstore release
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 17:45:08 +07:00
shakespeare.diy
e76076c1d9 Fix missing DialogTitle/SheetTitle accessibility warnings
Add visually-hidden (sr-only) titles to the three rendered dialogs/sheets
that were missing them:
- OnboardingPage relay-setup dialog (RelayEducation)
- Layout mobile navigation sheet
- MapPage spot detail bottom sheet

These satisfy Radix's accessibility requirement (screen readers announce
the dialog purpose) without altering the visual design.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 17:41:25 +07:00
shakespeare.diy
18f32a14bf Gate built-in Cashu mint wallet to native-only (browser CORS reality)
Browsers block most Cashu mints (no CORS headers), so minting/melting fails unreliably in-browser — and the failed fetches spam the console. Rather than ship a broken browser feature:

- CashuWalletCard: in a browser, render a clear "built-in ecash runs in the app" notice pointing users to zaps (NWC/WebLN/Lightning address) which work fine in-browser; full mint wallet renders only on native (Capacitor)
- useCashu: skip coco/IndexedDB/mint init entirely in the browser (isNativePlatform guard) — stops the recurring "Failed to fetch mint" console errors at the source
- Zaps/tips (the app's real money flow) are unaffected — they never touch a Cashu mint

Native builds get the full wallet with minibits working directly (no CORS jail), per the earlier platform-aware work.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 17:32:40 +07:00
shakespeare.diy
fc7564a6f8 Platform-aware wallet mints (Option C: native + browser scoping)
- Add @capacitor/core + src/lib/platform.ts (isNativePlatform/getPlatform, web-safe)
- mintReachability: on native (no CORS jail) short-circuit probe to 'ok' so ANY mint works, including mint.minibits.cash
- useCashu default mint: native prefers minibits (matches skatespots@minibits.cash brand identity) then coinos/21mint; browser uses CORS-friendly candidates
- MintPrivacyManager recommended list is platform-aware: native leads with Minibits (recommended), web leads with Coinos and flags Minibits as native-only
- CashuWallet: 'This mint can't be reached from your browser' banner for the browser CORS case (never shows on native), pointing users to a web-friendly mint or the native app
- Lightning invoice error mentions the native-app option

Same codebase now uses minibits directly when running as the native app, and a CORS-safe mint when running in a web browser.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 17:22:41 +07:00
shakespeare.diy
b830bf965d Auto-heal wallets stuck on a CORS-blocked mint
- useCashu now probes existing mints on every init (not just when empty); if none are browser-reachable it adds a reachable candidate mint. This fixes existing users whose only saved mint is the legacy CORS-blocked mint.minibits.cash default.
- CashuWallet active-mint selection now prefers the first browser-reachable mint instead of blindly mints[0], so users aren't stuck with a mint that fails every invoice.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 17:11:31 +07:00
shakespeare.diy
a0c59375ed Add crew chat moderation (client-side hide for E2EE group DMs)
- CrewChat: founder+admins can hide chat messages via a per-message hide button; reuses useCrewModeration/useHideCrewPost with the rumor (kind-14) message id
- Hidden messages filtered from chat for everyone; moderators see them greyed + "Hidden" (transparent/reversible)
- Since NIP-17 messages are E2EE and can't be deleted from relays, moderation is enforced client-side via public NIP-32 labels (label reveals only the hidden id, never content)
- Wire admins/crewCoord/canModerate from CrewDetailPage; header hint for moderators
- NIP.md: expand moderation section to cover both feed (kind-1 note id) and chat (kind-14 rumor id) with the E2EE client-side caveat

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 17:08:18 +07:00
shakespeare.diy
71d3d60d09 Harden wallet mints: browser-side CORS reachability probe
- Add mintReachability.ts: probe a mint's /v1/info from the user's browser to detect CORS-blocked ('cors-blocked') vs down ('unreachable') vs 'ok'
- useMintManager.handleAddMint: probe before adding; reject CORS-blocked/unreachable mints with a clear message instead of letting them fail later on invoice
- useCashu default mint: instead of hardcoding one (unverifiable at build time), probe an ordered list of web-friendly candidates and add the first that's reachable in-browser; minibits excluded (mobile-app only)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 17:04:43 +07:00
shakespeare.diy
f5483a0dbc Add crew admin moderation + invite actions
- useCrewModeration: fetch NIP-32 `hidden` labels authored by founder+admins for a crew; useHideCrewPost publishes a kind-1985 hidden label (L/l org.skatespots.moderation, e=post, a=crew)
- CrewDetailPage feed: moderators can hide posts via an EyeOff button + confirm dialog; hidden posts filtered from the feed for everyone, shown greyed/"Hidden from feed" to moderators (reversible/auditable)
- CrewInviteDialog: founder+admins share an invite link/message (native share + copy); founder gets a shortcut to add a member key in crew settings
- Gate all admin actions on useCrewRole().canManage; moderators = founder + delegated admins
- Add MODERATION_LABEL_NAMESPACE/HIDDEN constants
- NIP.md: document feed moderation label format (author must be founder/admin) + invite semantics

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 17:01:28 +07:00
shakespeare.diy
0078f75f94 Fix wallet invoice failure (CORS-blocked mint) + history crash
- Root cause: mint.minibits.cash sends no Access-Control-Allow-Origin header, so browsers block it (NetworkError → "Failed to create invoice / Failed to fetch mint"). Default to CORS-friendly mint.coinos.io instead.
- useLightningOperations: detect CORS/network failures on receive & send, show actionable "Can't reach this mint — switch mints" message instead of a dead end.
- MintPrivacyManager: reorder recommended mints by browser reachability; flag Minibits as mobile-app-only (not web-reachable).
- useHistoryManager: fix `mintQuoteRepository.getAll is not a function` crash by probing for whichever list method the installed coco-cashu version exposes (getAll/getAllQuotes/list/...), failing gracefully.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 16:53:40 +07:00
shakespeare.diy
40e4a27565 Add crew NIP-05 (any-domain, founder-verified) + founder/delegated-admin governance
- SkateCrew: add nip05 + admins fields; parse `admin` role marker on p tags (admins = subset of members)
- CrewForm: NIP-05 input + per-member "Make admin" toggle; write nip05 tag + admin-marked p tags (works on create & edit via shared form)
- useCrewNip05: verify crew handle on ANY domain against the founder pubkey (verified/mismatch/unreachable), CORS-proxy fallback + caching
- CrewNip05Badge: green ✓ / red ⚠ / muted handle states with tooltips
- CollectiveMembers: show Admin chips, sort admins first, admin count in summary
- useCrewRole: centralized founder/admin/member/none roles (canManage, canEditProfile) — founder owns identity, admins get delegated powers with their own keys; egalitarian shared-editing intentionally unsupported
- CrewDetailPage: NIP-05 badge by crew name, viewer role badges (admin/member)
- NIP.md: document crew nip05 verification, admin role marker, and governance/conflict-resolution model

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 16:46:20 +07:00
shakespeare.diy
e48a5e6bc5 Add duration tiers + layered NIP-57 zap verification, extend featured/Pro to tours
- Add 4 duration tiers (7d/30d/90d/365d) with per-day price discrimination to usePlatformFee
- PlatformFeePayment: tier selector UI + attempt NIP-57 zap request (a/p tags), graceful fallback to plain LNURL invoice
- Add getZapProviderPubkey + getZapInvoiceFromLightningAddress helpers
- Add useFeaturedVerification hook (verified/claimed/none) querying kind 9735 zap receipts
- ProBadge: optional entityCoord to show green Verified state on detail pages
- Wire entityCoord through all 5 Become* Lab pages + CoachDetailPage
- Add featuredTour fee type; FeaturedUpgrade generalized for events + tours
- CreateTourPage: featured tag on publish + FeaturedUpgrade UI
- TourCard/TourDetailPage: render ProBadge; sort featured tours first
- Document tiers + zap-receipt verification scheme in NIP.md

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 16:18:15 +07:00
shakespeare.diy
dcfa1fe1b2 Add Pro/Featured display + optional featured events (Option B)
Lab:
- useLabProfiles sorts featured (Pro) profiles first
- ProBadge shown on Lab cards (LabPage) + Lab detail page; featured cards
  get a subtle amber highlight

Events (same no-paywall model as Lab):
- New FeaturedEventUpgrade: every event posts for free; optional fee adds a
  featured badge + top placement (reuses existing featuredEvent fee)
- CreateEventPage: removed the paid-event fee gate; opt-in featured toggle,
  writes a `featured` tag when active
- useSkateEvents sorts featured events first; EventCard shows ProBadge
  (compact in list view, overlay on the image in full view)

Docs:
- NIP.md documents the `featured` tag (unix-seconds expiry, self-attested)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 15:39:41 +07:00
shakespeare.diy
5c0d4715d5 Rework Lab fee into optional "Pro" upgrade (Option B, no paywall)
Basic Lab profiles are now always free to publish. The 5,000 sat fee is
opt-in and unlocks a Pro badge + featured placement instead of gating
publication behind a rate.

- types.ts: `featuredUntil` field on all 5 Lab types + SkateEvent,
  parseFeaturedUntil() + isFeaturedActive() helpers, wired into parsers
- usePlatformFee: exposes featuredUntilSeconds for the `featured` tag
  (platform owners get a 1yr window)
- New ProBadge + LabProUpgrade (opt-in toggle → reveals PlatformFeePayment)
- All 5 Become pages: removed rate-based fee gate and wallet-required gate;
  publish is free; when Pro is active a `["featured", "<expiry>"]` tag is added

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 15:31:49 +07:00
shakespeare.diy
77dc4b562c Add Crew Chat: private E2E-encrypted group chat for crew members
Built on the existing NIP-17 gift-wrapped group DM system (useGroupConversation
+ useSendDirectMessage), so the relay only ever sees encrypted blobs.

- New CrewChat component: message list w/ author profiles, composer
  (Enter to send), auto-scroll, skeleton/empty states
- Participants = founder + all listed members (deduped)
- Only crew members can read/write (others see a locked "ask to join" state);
  warns if the signer lacks NIP-44
- "Private" lock badge makes the E2E-encrypted nature unmistakable
- Surfaced as a card on the crew detail page under the Crew Feed

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 15:18:39 +07:00
shakespeare.diy
e122ee826b Add "Public" badge to Spot Chat header + clearer privacy note
Makes it unmistakable that Spot Chat messages are public and unencrypted:
- Amber "🌐 Public" badge next to the title with an explanatory tooltip
- Footer note reworded to point users to Direct Messages for private chats

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 15:12:39 +07:00
shakespeare.diy
cf514a7c3f Add Photographers & Builders to community stats + restructure Lab section
- useGrowthStats now queries kind 35004 (photographers) and 35005 (builders),
  which were previously omitted; added to totals, monthly buckets, allContent,
  and the content-mix donut (folded into the "Lab" slice)
- Community Stats page reorganized into clear sub-sections:
  * "The Lab · Creators & Services" — Coaches, Filmers, Editors,
    Photographers, Builders, with a total badge
  * "Community" — Tours, Crews
  This scales the growing role list cleanly instead of cramming one row.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 15:06:18 +07:00
shakespeare.diy
3b25e7bcf6 Add trust filter to Spot Chat + include crews in community stats
Spot Chat:
- Compact TrustFilter dropdown in the chat header (All / Verified / Trusted / Following)
- Filters messages by author trust via useBatchTrustScores; own messages
  always stay visible; shows a "N hidden by your trust filter" indicator

Community stats:
- useGrowthStats now queries kind 35006 crews (was missing entirely)
- totalCrews added to totals + monthly buckets + content-mix donut
- New "Crews" StatCard on the Community Stats page

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 14:58:10 +07:00
shakespeare.diy
ba3921b15c Add Spot Chat: ephemeral geohash-anchored local chat channels
Inspired by BitChat's location-channel concept, reframed for skaters and
kept fully SkateSpots-native (own kind + tag conventions, no interop).

- New ephemeral kind 24899 tagged with a geohash `g` (documented in NIP.md)
- useSpotChat / useSendSpotChat hooks (polled, community-relay aware)
- SpotChat component: live message list, composer, author profiles,
  Block/Neighborhood/City precision toggle, and light IRC-style flavor
  (/me action messages, /who participant count)
- Spot detail pages now show a per-spot block-level channel
- Map gains a "Local Chat" sheet anchored to the map center with the
  precision selector

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 14:52:48 +07:00
shakespeare.diy
dec2e730d2 CVM find_crews: Sasquatch can now live-search crews
- useCVMClient: add findCrews (queries kind 35006 across data relays, filters by
  city/country/vibe/search, returns CrewResult with member_count, vibes, url);
  add crews to getCommunityStats + CrewResult type
- SasquatchGuide: register find_crews tool in system prompt + switch handler,
  add crew keywords to needsLiveData, update app-facts (crews are searchable +
  mention cross-linking and Zap-the-Crew)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 14:35:16 +07:00
shakespeare.diy
f881c6513f Zap a whole crew: split a zap across confirmed members
- useCrewZap hook: splits a total evenly across recipients, resolves each
  member's Lightning address (batched kind-0 query), fetches an invoice per
  recipient and auto-pays via NWC → WebLN; per-recipient status
  (resolving/paying/success/skipped/failed) with manual-invoice fallback
- splitAmount util distributes remainder fairly (no lost sats)
- ZapCrewDialog: amount presets + custom, per-head preview, live progress rows,
  copy-invoice fallback when no wallet; excludes the current user
- CrewDetailPage: "Zap the Crew" button (recipients = founder + confirmed
  members via useCollectiveMembers); shown only when >1 recipient

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 14:31:45 +07:00
shakespeare.diy
d8d1ba32c9 Nutzap safety gate + crew↔Lab cross-linking
Nutzap:
- Gate sending behind NUTZAP_SENDING_ENABLED=false with clear docs; sending
  would require P2PK-locking proofs (fund-loss risk if wrong), so it's disabled
  until implementable/auditable. Receiving + reading unchanged. No dead-end
  button exists (hook was never wired to UI).

Cross-linking crews ↔ Lab collectives:
- types: parseAddrCoord/parseCrewRef/parseLabRefs helpers + LAB_KINDS; add
  crewRef to all 5 Lab interfaces/parsers and labRefs[] to SkateCrew
- CrewLinkField (pick one of your own crews) added to all 5 Become-* forms,
  shown only for collectives; publishes an a-tag on the Lab profile
- LabLinkField (pick your own Lab profiles) added to CrewForm; publishes a-tags
- CrossLinkCards: LinkedCrewCard on Lab detail ("Part of a Crew"), LinkedLabCard
  on crew detail ("Hire This Crew"), resolving coordinates via useCrew/useLabProfile

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 14:27:51 +07:00
shakespeare.diy
ed27f719fa Sasquatch: teach him all the new features + fix zap comment
- Expand AI system prompt with full feature map: Lab (coaches/filmers/
  photographers/editors/builders + individual vs collective), Crews (map-anchored,
  how they differ from the Lab), Stash, Tours, Shops, Gear Swap, Rider Card
- Document money layer interconnections: wallet rails (Cashu/NWC/WebLN), zap
  fallback order, nutzaps (NIP-61, receiving), CLINK/noffer, Geyser supporters
- Instruct Sasquatch that Crews/Stash/Wallet/Tours/Shops have no live search tool
  and must be answered from knowledge (prevents bogus tool calls)
- Add ~15 new STATIC_FAQ offline answers (crews, stash, builder, nutzap, clink,
  noffer, tours, shops, sell gear, supporters)
- Add Crews page guide context + crew jokes; refresh Lab suggestions
- Fix leftover "Zapped with Engorile!" default comment → SkateSpots branding

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 14:12:30 +07:00
shakespeare.diy
28f4ef8c34 Crew form: refine vibes + multiple socials
- Remove LGBTQ+ and Longboard preset vibes
- Rename "Girls / Womxn" → "Girl / Woman"
- Add custom vibe/focus field: users define their own #hashtag focus
  (normalized to a lowercase hyphenated slug, published as t tags)
- Support multiple "Other Socials" links (SkateCrew.socials[]) with add/remove UI;
  parser collects all social tags; detail page renders each (URL or plain handle)
- Update NIP.md crew vibe taxonomy

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 14:06:37 +07:00
shakespeare.diy
f10aa7971c Step 3: Crews — map-anchored collective feature (kind 35006)
- New SkateCrew kind 35006 + type/parser + useCrews/useCrew hooks
- /crews directory, /create-crew, /edit-crew, /crew/:pubkey/:identifier pages
- Reuses the collective engine: NIP-32 membership attestation (confirmed/pending),
  CollectiveMembers + ConfirmMembershipCard, ClinkPayButton, SpotPicker
- Activity v1: home spots + crew member feed (no events, per plan)
- Map: teal/cyan Crews layer at home turf with crew markers + popups;
  wired through SpotMap props, layer toggles (mobile popover + filters sheet),
  and mobileLayerCount badge
- Nav: Crews added to navItemKeys (desktop header, mobile bottom bar, sidebar)
  with en/es i18n keys
- NIP.md: documents kind 35006, tag taxonomy, and shared membership mechanism

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 13:59:50 +07:00
shakespeare.diy
657c36d264 Add Builder category to The Lab (kind 35005), collective-aware + spot-linked
Step 2 of the collective plan:
- types.ts: SKATE_BUILDER_KIND 35005, BUILDER_SERVICE/SKILL/SCALE label maps,
  SkateBuilder interface + parseSkateBuilder (entity/members/noffer/spotRefs +
  service_area & insured fields)
- useLabProfiles/useLabProfile: query + parse builders (profileType 'builder')
- BecomeBuilderPage (/become-builder): amber accent, build-type/materials/scale
  chip selectors, "how we work" gear, service area, licensed/insured switch,
  entity toggle (defaults to collective), noffer, and "spots you've built" picker
- LabPage: 'building' ServiceType — amber accent, Builders tab (5 tabs now,
  horizontally scrollable on mobile), OfferFAB item, filter sections, card
  type-icon/labels, empty state, counts & filtering
- CoachDetailPage: builder accent/icon/kind, "What We Build" + "How We Work"
  sections, service-area & insured cards, portfolio/social handling
- NIP.md: document Builder kind 35005 with tag taxonomy + collective example

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 13:33:52 +07:00
shakespeare.diy
9cb8d1181d Add individual/collective entity type + NIP-32 membership attestation to The Lab
Step 1 of the collective plan (shared primitive on existing Lab categories):
- types.ts: EntityType + entity/members fields on coach/filmer/editor/
  photographer interfaces & parsers; membership label namespace constants +
  parseMemberPubkeys / parseEntityType helpers
- useCollectiveMembers: cross-references claimed `p` tags against members'
  own NIP-32 (kind 1985) attestations -> confirmed / pending status
- useConfirmMembership: publishes a member's self-signed membership label
- EntityTypeField: individual/collective toggle + member npub picker (per-
  category accent) wired into all 4 Become-* forms
- CollectiveMembers: sidebar card with confirmed/pending trust chips
- ConfirmMembershipCard: one-tap confirm shown only to listed pending members
- CoachDetailPage: collective badge, members card, confirm-membership prompt
- Lab cards: compact collective badge with member count
- NIP.md: document entity tag + collective membership attestation flow

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 13:18:18 +07:00
shakespeare.diy
feddbaf5ef Add optional CLINK (noffer) self-custodial payments to Lab profiles + shops
Phase 1 CLINK integration (recognize & display only):
- types.ts: optional noffer field + isValidNoffer guard on SkateCoach,
  SkateFilmer, SkateEditor, SkatePhotographer, SkateShop; parsers read it
- NofferField: reusable opt-in input with live validation, added to all 4
  Become-* Lab forms and both Create/Edit shop forms
- ClinkPayButton: secondary "Pay via CLINK" action (QR + copy + nostr: deep
  link), rendered on CoachDetailPage and ShopDetailPage only when a valid
  noffer is present; never replaces the existing zap / Lightning Address flow
- useQRCodeScanner: classify scanned noffer1/ndebit1 CLINK codes
- NIP.md: document the noffer tag on Lab kinds + shops and a CLINK section

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 12:34:50 +07:00
shakespeare.diy
adeab62aa4 Add Photographer card to The Lab (kind 35004) + improve Filmer section
New Photographers category (blue-indigo) — separate from Filmers:
- New addressable kind 35004 + SkatePhotographer type + parseSkatePhotographer.
- Rich photographer taxonomy as queryable `t` tags: services (action,
  sequence, editorial, product, events…), camera bodies, lenses, lighting
  (Profoto/Elinchrom/Godox/triggers…), support/rig, and shooting style,
  plus a freeform "gear" tag and a portfolio link.
- BecomePhotographerPage form with chip-grid selectors for all gear
  categories + "what's in the bag" textarea, wired to /become-photographer.
- The Lab: 4th "Photo" tab (indigo accent) with its own filters, cards,
  empty state; OfferFAB gains "Offer Photography"; useLabProfiles fetches
  35004; CoachDetailPage renders photographers (and editors) properly with
  per-type accent, gear + portfolio display.
- NIP.md: documented the whole Lab (kinds 35001-35004) incl. photographer.

Filmer improvements (now video-focused, photography split out):
- Removed the token "Action Photography" service; added follow/line filming.
- Richer equipment list: cinema camera, HVX, action cam, gimbal, 4K/HFR.
- Filmers gain a freeform "what's in the bag" gear field + a reel/portfolio
  link, both surfaced on the detail page.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 11:27:22 +07:00
shakespeare.diy
88a36e52ae Add Events as an opt-in map layer
Events can now be discovered directly on the map:
- New "Events" layer (lime #ccff00, calendar pin marker) plotting upcoming,
  geo-located events. Off by default — users opt in via the Layers control.
- Event markers show a popup with title, date/time, location, and a
  "View Event" button linking to the event detail page.
- Only future/ongoing events with a valid geohash are plotted (past events
  are filtered out to keep the map clean).
- Added to the mobile Layers popover, desktop Layers popover, and the mobile
  filter drawer's "Show on Map" grid. Layer count badge now tracks 5 layers.
- SpotMap gains `events` + `showEvents` props and a createEventIcon marker.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 10:48:24 +07:00
shakespeare.diy
88d610c947 Add "Add Event" and "Sell Gear" to the map Add speed-dial
The mobile "+" speed-dial was missing two core actions:
- Add Event (lime #ccff00, Calendar icon) -> /create-event
- Sell Gear (orange #f97316, ShoppingBag icon) -> /create-listing

Now fans out: Add Spot / Add Shop / Add Event / Sell Gear / Offer Tour /
Quick Snap. Colors follow the canonical entity palette. Bumped Quick Snap's
stagger delay so it animates in last.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 10:36:48 +07:00
shakespeare.diy
aa4c5ca697 Desktop map Layers popover (#6) + canonical entity colors (#7)
#6 Desktop parity:
- Replaced the four separate Spots/Shops/Gear/Tours toggle buttons in the
  desktop map toolbar with a single grouped "Layers" popover (with count
  badge), matching the mobile control. Declutters the dense toolbar row.

#7 Entity color discipline:
- Locked the four map-entity colors to a single canonical value each,
  matching the map markers (source of truth): Spots #ff0040, Shops #9333ea,
  Gear #f97316, Tours #06b6d4.
- Fixed the mismatch I'd introduced (Layers popover + Add FAB used #a855f7
  purple instead of the marker's #9333ea). Everything now agrees.

Note: broader purple usage (Stash, Cashu, NWC, Editors) is intentionally
left as-is — those are separate semantic uses, not the map entity language.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 10:32:57 +07:00
shakespeare.diy
bb6b3e6b7e Fix map search input visibility; align header sizes; de-dupe map Quick Actions
- Map search input: replaced non-standard `bg-white/6` with `bg-white/5`
  (matching The Lab's inputs) and removed the focus ring offset so typed
  text is now visible on the dark toolbar instead of a white field. Also
  normalized the mobile filter button's `bg-white/6` -> `bg-white/5`.
- Bumped Wallet and Settings page titles to text-4xl md:text-5xl to match
  The Lab and Events headers for consistent title rhythm.
- Trimmed the map filter drawer's Quick Actions to Marketplace + Stash,
  since Add Spot / Shop / Tour / Quick Snap now live in the Add speed-dial
  FAB (removes duplication).

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 10:24:52 +07:00
shakespeare.diy
1d1e6d18b1 Redesign mobile map controls: Layers popover + Add speed-dial FAB
Replaces the crowded 12-item vertical right rail with a clean, minimal set:
- Right edge now has just two 44px controls: Near Me and a Layers button.
- Layers opens a labelled popover (Spots/Shops/Gear/Tours) with color dots
  and checkmarks, plus a count badge on the button so state is obvious.
- All "add" actions consolidated into a single red speed-dial FAB
  (bottom-right) that fans out to Add Spot / Add Shop / Offer Tour /
  Quick Snap, with a tap-catcher backdrop to dismiss.
- Sasquatch bubble moved to bottom-left on mobile so it no longer competes
  with the Add FAB for the bottom-right corner.
- Larger touch targets (44px) for better native/ZapStore ergonomics.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 10:18:35 +07:00
shakespeare.diy
d107c0a860 Fix Sasquatch auto-popup on / and /lab; move map attribution above mobile nav
- Sasquatch panel no longer auto-opens on the map (/) or The Lab (/lab).
  Added an `autoShow` flag to GuideMessage; only opt-in messages (onboarding)
  auto-open. The bubble stays minimized until tapped, and context messages
  still populate the panel when opened manually.
- Map CARTO/OSM attribution now sits above the mobile bottom nav (safe-area
  aware) instead of overlapping the Shops & Spots buttons; made it smaller
  and more subtle. Desktop keeps it in the bottom-left corner.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 10:09:15 +07:00
shakespeare.diy
a74225fe0d feat: platform monetization — listing fees for paid events & Lab profiles v1.0.62
Architecture:
- usePlatformFee hook: central fee config (featuredEvent/labProfile/featuredShop)
  5,000 sats each, 30-day validity, localStorage persistence, owner bypass
- PlatformFeePayment component: generic reusable payment gate
  auto-pay via NWC/WebLN, QR fallback, active/expired state display
  all fees route to skatespots@minibits.cash

Events (CreateEventPage):
- New optional "Entry Fee" field
- Triggers 5,000 sat platform fee when filled
- Stores entry-fee + paid tags on published event
- Free events: zero friction unchanged

The Lab (Become{Coach,Filmer,Editor}Page):
- Triggers 5,000 sat fee when "Rate" field is filled
- Submit disabled with clear CTA until fee paid
- Free/volunteer profiles: zero friction unchanged

Rule: "pay only when you earn"
- No rate set → publish instantly, no fee
- Rate set → 5,000 sats to SkateSpots, valid 30 days
- Platform owners always bypass

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 02:19:45 +07:00
shakespeare.diy
d8e49e7f65 redesign: /onboarding full rewrite
Hero:
- "SKATE YOUR WORLD" headline with neon red/lime treatment
- Beta badge pill with live pulse dot
- Feature pills row (spots, lab, events, gear, stash, radio, zaps)
- Primary CTA right in the hero — no scrolling to get started
- "No email. No password. Own your identity forever." copy

Layout:
- Removed mechanical 4-step progress tracker (step 2 auto-completing was confusing)
- Replaced with natural scrolling sections with clear headings
- Logged-in state shows green confirmation bar with FounderFollow

What you can do:
- 6-card grid: Map, Lab, Events, Buy/Sell, Stash, Radio — all linked

What is Nostr:
- Skater-friendly explanation with 4 benefit pills
- Deep dive button for relay education modal

Zaps & Wallet:
- "Optional" badge so new users don't feel overwhelmed
- Side-by-side: Cashu (built-in) + External wallet (NWC)

FAQ (accordion — 8 questions, no duplicates):
- "Is it free?" — combined the two identical free questions
- "What is Nostr?" — proper explanation
- "What's an nsec?" — key backup warning
- "What signers work?" — desktop/Android/iOS with real links
- "Can I use it on my phone?" — PWA + Zapstore mention
- "What is a zap?" — simple skater framing
- "Will my spots be deleted?" — relay permanence
- "Private property spots?" — community responsibility
- "How to report a bug?" — links to cordn.net beta coordinator

Beta section:
- cordn.net/p/npub1e2ayjl... as primary beta contact (clickable card)
- Founder npub with Copy + DM buttons as secondary
- Removed v0.1.0 hardcoded version string

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 02:00:12 +07:00
shakespeare.diy
254484a354 fix: add Add Spot (red) + Add Shop (green) back into right control strip
- Both + buttons are 36px circles matching the strip visual system
- Add Spot = red circle (bottom of layer toggles section)
- Add Shop = green circle (right below Add Spot)
- Removed redundant left-side FAB entirely — everything is now in one column on the right

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 01:51:18 +07:00
shakespeare.diy
056846fc38 redesign: map page mobile UI overhaul v1.0.61
Toolbar:
- Slim rounded-pill search input (was tall boxy default)
- Compact icon-only view toggle pills
- Small circle filter button (red when active, badge count)

Right-side control strip:
- Layer toggles (Spots/Shops/Gear/Tours) as 36px circles
  active=opaque, inactive=35% opacity — no more giant emoji FABs
- Near Me button integrated into strip (removed from top-right)
- Quick Snap in strip, same style — no more big red circle
- All transitions: translate-x-2 slide-out when overlays open

Left-side Add FAB:
- Single gradient pill (red→orange) replaces two competing circles
- Smaller footprint, less visual noise

Loading indicator:
- Replaced center-screen "Loading..." pill with slim animated
  gradient bar at top edge of map (top-0 left-0 right-0 h-0.5)

Attribution:
- Moved from floating top-right to bottom-left corner
- 9px text, 50% opacity — required but invisible

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 01:49:07 +07:00
shakespeare.diy
7335255f37 chore: update release-notes.txt for v1.0.60
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 01:33:29 +07:00
shakespeare.diy
46be2d9176 chore: bump version to 1.0.60
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 01:30:19 +07:00
shakespeare.diy
f39c251e90 fix: Sheet z-index — burger menu now covers all map floating buttons
Map FABs and controls sit at z-[1000]–z-[1001]. The Sheet overlay/content
were at z-50 (= 50), so the map buttons punched through on top.

Bumped SheetOverlay and SheetContent from z-50 → z-[2100], which is above
the highest map element (z-[2001] for the spot detail modal) so the slide-in
drawer always fully covers the map UI.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 01:25:46 +07:00
shakespeare.diy
76b834ddd2 redesign /stash desktop layout — premium sidebar, tighter grid, better hierarchy
- Sidebar expanded to 300px with real visual weight
- Inventory card: big stat number (e.g. "5 items in stash"), est. sats value, 3-cell secondary stats row (Wishlist / For Sale / To Trade), clickable category breakdown bars
- Marketplace CTA: gradient header with branded icon, per-type badges showing sell/trade counts, full-width gradient CTA button
- Wishlist teaser card: number callout + "View Wishlist" action button
- Quick-add buttons (Add to Stash / Add to Wishlist) moved to top of sidebar on desktop — header no longer needs them
- Grid defaults to 2/3/4 cols (sm/md/xl) — no more awkward single-item stretch
- Empty states bigger and more purposeful with better copy
- Mobile layout unchanged; FABs and mobile CTA banner retained

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 01:20:38 +07:00
shakespeare.diy
f68864bb8f redesign: Stash page v2 — eliminate noise, get to items faster
- REMOVED: Sync banner (already in header subtitle)
- REMOVED: ProfileStatsBar self-intro card (it's YOUR page, you know who you are)
- REMOVED: Chunky tab switcher — replaced with underline tabs inside the sticky header,
  saving ~50px of vertical space before you see any items
- MERGED: All header info (title + item count + encryption + sats value) into one
  compact 56px sticky bar — nothing duplicated
- IMPROVED: Search + category filter in a single tight row (h-9 inputs)
- IMPROVED: Category chips only render when >1 category present (no orphan chips)
- IMPROVED: Sidebar is desktop-only (lg:hidden) — on mobile it was buried below items,
  now replaced by a contextual bottom banner that only appears when items are for sale
- IMPROVED: FABs slightly smaller (not competing with Sasquatch bubble)
- IMPROVED: Empty state is more focused — no walls of text

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 01:04:41 +07:00
shakespeare.diy
df64a44c4e fix: remove duplicate Browse Marketplace button in Stash sidebar
Merged the two separate marketplace cards (Ready to Sell + Stash→Marketplace)
into a single smart card:
- When items are marked for sale/trade: shows orange "Ready to Sell" CTA
  with item count and a prominent Browse Marketplace button
- When no items for sale: shows a quieter grey card explaining how to
  mark items for sale, with a subdued Browse Marketplace link
One card, one button, no duplication.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 00:54:50 +07:00
shakespeare.diy
2cfb1ad566 redesign: Stash page full UX overhaul
Key improvements:
- NEW: List view (default) — compact swipeable rows for mobile, perfect
  for scanning inventory quickly. Grid view still available via toggle.
- NEW: Floating FABs on mobile — red + to add to stash, cyan heart to
  add to wishlist, positioned above the nav bar with safe-area support
- NEW: Cross-device sync info banner explaining Nostr = synced everywhere
  (answers the user's question: yes, items added on desktop show on mobile)
- FIX: "Browse Marketplace" now navigates to /marketplace (GearSwapPage)
  instead of /map?view=gear which incorrectly loaded the map
- NEW: Sticky page header with item count badge, encrypt indicator, and
  view-mode toggle — always visible when scrolling
- NEW: Compact ProfileStatsBar replaces the heavy CharacterPanel sidebar card
- NEW: Category quick-chips — tap an emoji to filter by category instantly
- IMPROVED: Location filter only shows locations that have items (no empty chips)
- IMPROVED: Sidebar consolidated — removed redundant cards, kept what matters:
  "Ready to Sell" card (only shown if items are marked for sale), marketplace
  link, wishlist status, and compact tips
- IMPROVED: Empty states mention cross-device sync as a feature
- IMPROVED: List row actions are always visible (no hover-only on mobile)

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 00:51:18 +07:00
shakespeare.diy
eba7542097 fix: FAB buttons above nav + Sasquatch no auto-trigger on map
- FABs (add spot/shop): switch from fixed bottom-[88px] to
  calc(3.5rem + env(safe-area-inset-bottom, 0px) + 0.75rem) so they
  respect device safe-area and always clear the bottom nav on all
  Android/iOS Capacitor builds
- Right-side filter pills: same fix, switched from absolute to fixed
  with the same safe-area-aware bottom value
- useSasquatchGuide: /map page now returns undefined message, meaning
  Sasquatch never auto-opens when navigating to Shops & Spots — user
  must tap the floating bubble to open it manually

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-07-24 00:12:53 +07:00