Commit graph

10 commits

Author SHA1 Message Date
SkateSpots
8dcc97fd81 feat(app-shop): add the App Shop section (empty on purpose)
New /app-shop page for SkateSpots merch, to be paid in sats only (Lightning or
Cashu) — no cards, no accounts, no middleman.

Design: gradient/glow hero ('Wear the scene' + Coming soon badge), an honest
stock strip (0 items / None pre-orders / Nothing for sale today), an 'In the
works' teaser grid (tees, decks, stickers, tools — dashed + 'soon', no prices),
a three-step 'How it'll work' (pick -> pay in sats -> ships), a newsletter
notify band (the drop lands there first) and a plain-English honesty footer.

Deliberately contains no items: no stock, no prices, no pre-orders, no buy
buttons. AGENTS.md documents that rule so nobody invents a catalogue later.

Wiring: registered in NAV_CATALOG as id 'app-shop' (appears in the desktop
'More' menu AND the mobile burger menu automatically), lazy route in AppRouter,
and added to the smoke-test route list so a broken page aborts deploys.

Verified: page renders desktop + mobile (all sections), listed in both navs,
smoke PASS with /app-shop.
2026-09-27 21:40:41 +07:00
SkateSpots
a881a87f4d feat(lab): add Barber / Hairstylist profile (kind 35014)
A full Lab role, mirroring how Event Organizer was added:
- kinds: SKATE_BARBER_KIND 35014, self-tag 'skatebarber', BARBER_*_LABELS,
  SkateBarber + parseSkateBarber (studio, books_open).
- craft config at /become/barber (cyan accent, Sparkles icon), Lab tab
  'Barbers', filter sections (services/styles/setting), empty state, FAB item.
- Lab pipeline: useLabProfiles kind/tag/parser, LabPage ServiceType
  'barbering' + ACCENT/maps/counts, CoachDetailPage per-role maps + studio &
  books-open block, LabLinkField label, growth stats + Community Stats card.
- No crew-scene strip for barbers (LabCrewsStrip returns null).
- Documented in NIP.md; smoke test now boots /become/barber.
2026-09-27 10:15:30 +07:00
SkateSpots
b60b13dc18 feat(lab): add Event Organizer craft profile (kind 35013)
New data-driven Lab role 'Event Organizer / Host' — skaters who put on jams,
comps, meetups, demos and tour stops.
- types.ts: SKATE_ORGANIZER_KIND=35013, ORGANIZER_EVENT/SERVICE/SCALE label
  maps, SkateOrganizer + parseSkateOrganizer (events_hosted extra tag)
- becomeRoles: craft config (teal accent, Tent icon, 3 skill sections)
- useLabProfiles: registered kind/self-tag/parser
- LabPage: Organizers tab, accent, filter drawer section, empty state, Offer
  link, counts
- CoachDetailPage (generic Lab detail): accent/icon/kind/labels/noun
- LabCrewsStrip: union updated
- NIP.md documents kind 35013; smoke covers /lab and /become/organizer

Gate: 101 tests, 0 errors/warnings, boot smoke green.
2026-09-27 00:02:39 +07:00
SkateSpots
5b163c632f feat(trades): My Trades page + block-filter DM relays
- New '/trades' page: action-needed (incoming 'confirm this sale' requests as
  seller, pending confirmations as buyer) with inline actions, a reputation
  card, and the user's own trade records (role/counterparty/state) linking to
  each listing. Nav entry (auth-only) + smoke route.
- DM inbox relays (kind 10050) are now block-filtered on both read and delivery
  (closes the last relay caveat).
- AGENTS.md updated.

Gate: 101 tests, 0 errors/warnings, boot smoke green.
2026-09-26 22:56:52 +07:00
SkateSpots
5d1a0e0fb0 feat(marketplace): listing detail page + shared trade/escrow actions
- New '/listing/:pubkey/:identifier' page: large gallery + lightbox, full
  description, details, seller trust + trade reputation card, and full actions
  (shared) for buyers and owners (mark sold/relist/delete)
- Extract ListingTradeActions (confirm/escrow request/ask-to-confirm/refund/
  contact + escrow dialog) and use it in BOTH the grid card and the detail page
  so there is one implementation
- useMarketplaceItem(pubkey, identifier) fetch hook
- Cards link their image + title to the detail page
- Smoke test covers /listing/:pubkey/:identifier

Gate: 101 tests, 0 errors/warnings, boot smoke green.
2026-09-26 22:30:43 +07:00
SkateSpots
a1c30cad4e feat(mints): Cashu mint directory (MintRadar) + same-origin proxy
New '/mints' page: browse Community MintRadar mints with health (online/latency/
degraded/archived), NUT count, terms, and add-to-wallet on native.

MintRadar has no CORS, so it's fetched same-origin at /api/mints/*:
- prod: Netlify proxy redirect in public/_redirects (+ 10m cache in _headers)
- dev: Vite server.proxy in vite.config.ts
This also hides users' IPs from MintRadar. Data is unofficial/rate-limited;
the page degrades to a friendly error state. Nav entry + smoke route added.
2026-09-26 21:20:19 +07:00
SkateSpots
b91df1b4b0 feat(marketplace): trade confirmation requests (kind 31872) + fix boot smoke test
Marketplace:
- Buyer can 'Ask seller to confirm' a sold listing -> publishes a 31872
  Attestation Request (d/a/p), which the seller fulfils in one tap
- Seller sees incoming requests in the DM thread ('Confirm this sale?') and the
  fulfilling 31871 carries the spec's 'request' tag
- useTradeAttestationRequest / useIncomingTradeRequests / useListingTradeRequest
- NIP.md documents 31872 and states escrow is intentionally NOT implemented
  (coco-cashu has no P2PK/HTLC locking, wallet is native-only, and release-on-
  attestation needs a witness) so nothing looks trustless that isn't

Hardening:
- scripts/smoke-test.mjs navigated to /settings etc. WITHOUT a hash, so with
  HashRouter it only ever loaded the homepage and reported PASS. It now puts the
  route in the hash, covers settings/stash/collections/stats/marketplace, and
  fails on the 'This page slammed' error boundary (not just boot failure)
2026-09-26 20:47:29 +07:00
SkateSpots
2a47e5c9c5 feat(dm): group DMs (NIP-17) — inbox list + group thread
Uses the existing gift-wrap primitive (kind 14 rumor, one p-tag per recipient):
- useGroupConversations: lists multi-recipient threads, bucketed by the sorted
  participant key; the inbox shows a Groups section
- GroupConversationPage (/messages/group/:participants): encrypted group thread
  with sender names, send + error feedback
- smoke test now boots the new route

Group creation UI (multi-select in NewMessageDialog) is the next step. For
stronger guarantees (forward secrecy, rosters) Marmot/MLS or Cordn would be the
protocol to adopt later; noted in the hook.
2026-09-26 19:52:33 +07:00
SkateSpots
6ae4e674dc feat(leaderboards): zap leaderboards page (top spots + top supporters)
New /leaderboards route (linked from the More menu): aggregates kind-9735
receipts into top-zapped spots and top supporters, with week/month/all-time
tabs. Reuses the batched zap helpers. Also hardens the deploy smoke test to
boot lazy routes (/, /leaderboards, /bounties), since route chunks can fail
independently.
2026-09-26 17:17:21 +07:00
SkateSpots
acdde497b4 feat(deploy): boot-test the built bundle before deploying; document the vite chunking gotcha 2026-09-26 16:57:17 +07:00