Commit graph

7 commits

Author SHA1 Message Date
SkateSpots
e016ee20bd fix: tier 3 — medium bugs & hardening
- Tour sponsor URL/logo sanitized before href/src (SponsorSlot) — same XSS
  guard EventSponsors already uses.
- Official SkateSpots badge only shows when the NIP-05 actually verifies
  (NIP19Page), not on a self-asserted handle.
- Community stats reads are null-guarded on persisted-cache fields
  (monthly/cumulativeSpots/topMappers) — no more crash on an old cache.
- Overpass response no longer assumes .elements (food layer).
- user-listings query key is memoized (was Date.now() → refetch storm).
- Pro grant requires the l=pro label (was accepted with none).
- Verify card RSVP maps accepted/tentative (was going/interested → showed
  'No RSVP' on a valid ticket).
- Expired listings can't be bought via a stale/shared URL.
- Batch spot photo/status hooks include the relay suffix and use
  querySkateContent (relay-policy parity with useSpotReports).
- Offline queue requeues rows stuck in 'publishing' after a crash.
- querySkateContent/queryCanonical dedupe replaceable events by author+kind
  (not id) so a stale profile/relay list can't win.
- Route offline cache key includes the origin (was destination+mode only).
- Internal links use <Link> (MarketplacePage); EventCountdown reacts to
  language changes.
2026-10-02 22:26:46 +07:00
SkateSpots
0b796440f1 feat(i18n): Spanish batch 2 — nav/chrome, events/shops/tours, crews/DMs, settings/auth, wallet/stash/newsletter/stats
~3,470 new keys (5,770 total, EN=ES), ~115 more files wired.
- nav + chromeUi: header, More menu, burger menu, footer, map toolbar widgets
  (sort/trust/weather), spot-type label helper.
- placesUi: events, shops, tours, food. socialUi: crews, DMs, notifications,
  collectives, crew chat/coordinator. settingsUi: settings, auth/signup,
  onboarding, profile edit, legal. walletUi: wallet/Cashu, stash, mints,
  app shop, newsletter, community stats, leaderboards, profile.
- Fixed 738 usages where an agent dropped the socialUi. prefix (caught by check:i18n).
2026-10-02 10:11:06 +07:00
SkateSpots
b2a6108eeb refactor: split non-component exports (react-refresh) into their own modules
Removes the last react-refresh disables by splitting exports instead:
- contexts/language.ts: Language/Translations types + LanguageContext +
  useTranslation/useT (LanguageProvider stays a component-only file); 12
  importers repointed.
- lib/sortOptions.ts: calculatePopularity + calculateDistance (out of SortDropdown)
- lib/trustFilter.ts: TrustFilterLevel + filterByTrustLevel (out of TrustFilter)
- EventCountdown: deleted the unused useEventStatus hook
- NewsletterPage: dropped the NEWSLETTER_ISSUES re-export shim
- AGENTS.md updated (lint stays clean with no blanket disables)

Gate: 101 tests, 0 errors/warnings, boot smoke green.
2026-09-26 23:29:42 +07:00
SkateSpots
c0aec3d912 chore(lint): reach zero warnings (react-refresh)
The last 7 react-refresh warnings are dev-only HMR DX from intentional
component+hook/helper colocations (EventCountdown, SortDropdown, TrustFilter,
LanguageContext, NewsletterPage). Splitting them into new files is broad import
churn for no runtime benefit, so each carries a justified file-level disable.

npm test: 0 errors, 0 warnings, 101 tests; boot smoke green.
2026-09-26 22:23:45 +07:00
SkateSpots
721a5d4b67 chore(lint): clear all react-hooks/exhaustive-deps warnings
Triage per file (not a blanket sweep):
- Memoise shared getters with useCallback and depend on them:
  EventsPage/LabPage/MapPage getTrustScore+getCommentCount (+MapPage getZapTotal)
- Memoise derived values that were recreated each render: CrewChat 'messages',
  RiderCardPage 'cardData'
- Justified eslint-disable for intentional mount-only effects with a comment:
  AppProvider (seed defaults/theme), SpotMap (Leaflet init once),
  SpamFeePayment (auto-pay keyed to invoice/state, not the recreated handler)
- EventCountdown: keep the intentional 'tick' recompute dep (documented disable)

exhaustive-deps: 14 -> 0. Warnings 60 -> 46 (39 unused-vars, 7 react-refresh).
Gate: 101 tests, 0 errors, boot smoke green. AGENTS.md baseline updated.
2026-09-26 22:09:43 +07:00
shakespeare.diy
25c57cbb2f Fix event UX correctness: live countdown, cancellation banner, NIP-52 tag cleanup
- FIX: EventCountdown label never updated (memo ignored the interval tick) — now recomputes every 30s for both EventCountdown and useEventStatus
- Add loud cancelled / rescheduled banner on EventDetailPage derived from host updates; close RSVP + dim hero when cancelled so attendees don't show up to a dead jam
- Clean up non-standard NIP-52 `a` tags (['a', coord, '', ''] → ['a', coord]) in RSVP and host-update publishing
- Correct misleading kind comment in useEventRsvps

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-03 14:33:28 +07:00
shakespeare.diy
87c81a63c9 Event detail hero redesign + live countdown + sponsors
- Immersive EventDetailPage hero: full-bleed cover with legibility gradient,
  bold uppercase title, type pills, host/music-act chips, and a 3-up meta bar
  (date block · time · where). Past events render dimmed.
- EventCountdown: live status pill — "IN 3 DAYS" / "IN 2H 14M" /
  "HAPPENING NOW" (pulsing) / "ENDED", refreshing every 30s.
- Actions (edit/calendar/share) moved into a clean glass overlay on the cover.
- Event sponsors: EventSponsor type + parse/serialize (mirrors TourSponsor),
  EventSponsors "Presented by" strip (title sponsor hero row + logo grid),
  sponsor editor on CreateEventPage, and sponsor preservation on edit.
- Document event sponsor tag in NIP.md.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-09-03 12:04:07 +07:00