Commit Graph

4447 Commits

Author SHA1 Message Date
Alex Gleason 77db5965a9 Add per-beneficiary donate dialog on campaign page
Each beneficiary listed on a campaign page now has a Donate button
next to it. Clicking it opens a dialog that shows the beneficiary's
Bitcoin (Taproot) address — derived from their Nostr pubkey — as a
scannable BIP-21 QR code and a copyable address.

This is distinct from the existing campaign DonateDialog, which
splits across all recipients. The new dialog targets a single
beneficiary directly, so it intentionally skips amount entry and
the campaign-tally flow.
2026-05-18 18:38:17 -05:00
filemon 2f8569c302 Fix five small UI polish issues
- Push Leaflet zoom controls below the sticky header on /world so they
  remain clickable instead of sitting behind the 64px top bar.
- Replace plain <a> tags with React Router <Link> in the site footer so
  navigation to /help, /privacy, /safety, and /changelog is client-side
  instead of triggering a full page reload.
- Use plain-text preview with line-clamp-3 in the post more-menu instead
  of NoteContent + a conflicting max-h hard clip, so long content
  truncates with an ellipsis rather than cutting off abruptly.
- Switch the campaign detail Donate/Share row from a rigid 4-column grid
  to flex so the Share button gets its natural width instead of being
  cramped into 25% of the row on mobile.
- Make the campaign URL preview in /campaigns/new truncate with an
  ellipsis for long slugs instead of overflowing or clipping silently.
2026-05-18 20:09:36 -03:00
Alex Gleason 7465ad01d4 Hide top-nav Start Campaign button when logged out 2026-05-18 17:45:40 -05:00
Alex Gleason ab9e8bfcd6 Hide campaign progress bar when no goal is set 2026-05-18 16:55:45 -05:00
Alex Gleason d71d6de05f Publish a single kind 8333 receipt per donation tx
A single Bitcoin transaction with N outputs now produces a single kind
8333 onchain-zap event listing every recipient under its own `p` tag,
instead of one event per recipient. The `amount` tag carries the total
sats paid to the listed recipients (the full donation, excluding the
donor's change).

This is straight-forward forward-compatibility: legacy single-recipient
events are just the degenerate case (one `p` tag, amount equal to the
one recipient's slice). Aggregators (`useCampaignDonations`,
`useGlobalDonations`) simplify to summing the `amount` tag across every
matching event — under both schemas an event's `amount` is the total
paid to the recipients listed in that event, so the sum across all
events for a campaign is the campaign total either way.

The verifier (`verifyOnchainZap`) now sums tx outputs paying any listed
recipient's derived Taproot address and strips the sender from the
recipient set so a tx that includes the sender plus legitimate
recipients still verifies. The notifications surface uses a new
`getZapAmountSatsForRecipient` helper to attribute only the viewer's
estimated slice (amount / p_count) rather than crediting them with the
full multi-recipient donation. `CampaignDetailPage` keeps its
group-by-(txid, donor) reply rendering so legacy multi-event donations
still collapse to a single donation card.
2026-05-18 16:36:32 -05:00
filemon f9eec18adb Merge branch 'main' into dashboard-ui-polish 2026-05-18 16:10:50 -03:00
filemon ba08d749ac Remove sidebar add/remove button from dashboard header 2026-05-18 15:55:44 -03:00
filemon 6eccacc06a Update getStableCount comment to reflect current usage
The comment said it was not used in participants, but it now is.
2026-05-18 14:59:48 -03:00
Chad Curtis 8feaccf5dd Increase world map default zoom and recenter on Atlantic 2026-05-18 12:55:18 -05:00
Chad Curtis 1ac62aac06 Add photo banner heroes to organize and actions 2026-05-18 12:52:54 -05:00
lemon 041979de07 Tighten mobile nav spacing 2026-05-18 10:48:44 -07:00
lemon 59556406a8 Move mobile footer links below CTA 2026-05-18 10:47:04 -07:00
lemon 58bb3046e7 Reorganize sidebar navigation 2026-05-18 10:43:49 -07:00
filemon 45242292d6 Use stable COUNT floor for participants list counts
Apply getStableCount to the participants/full-state-list section so
per-state numbers are consistent with the leaderboard and distribution
chart. Previously the participants list used raw event-based counts
while the other sections used NIP-45 COUNT floors, causing visible
mismatches (e.g. Miranda showing 847 in the list but 859 in the donut).

In municipalities view this is a no-op — getStableCount returns the raw
feed.count unchanged since there are no per-municipality COUNT queries.

Live/activity indicators still derive from loaded events.
2026-05-18 14:32:50 -03:00
lemon ef9adb29e8 Update primary navigation 2026-05-18 10:30:15 -07:00
lemon 1d5f0541d7 Clone discover hero ticker 2026-05-18 10:26:04 -07:00
lemon 0671910e67 Match organize hero ticker style 2026-05-18 10:24:51 -07:00
filemon 7bb960b6b3 Align dashboard header with content column and add bottom spacing
Pass max-w-5xl mx-auto sm:px-6 to PageHeader via its className prop so
the title and action buttons sit inside the same centered column as the
dashboard body.  This is a local override — the shared PageHeader
component is not modified.

Add pb-8 to the content container for comfortable breathing room between
the last dashboard section and the footer.
2026-05-18 14:24:20 -03:00
lemon e71d95fcc6 Refine organize hero copy 2026-05-18 10:23:43 -07:00
lemon 84496d30a1 Align organize hero with discover 2026-05-18 10:17:35 -07:00
filemon a0ca42af26 Polish dashboard page to match app design system
Normalize the dashboard layout and card styling for visual consistency
with the rest of the app. No data fetching or behavioral changes.

Page container:
- Widen content from max-w-4xl to max-w-5xl (justifies noMaxWidth opt-out)
- Add responsive padding (px-4 sm:px-6)
- Replace non-standard pb-24 with pb-16 sidebar:pb-0
- Add min-h-screen to prevent short-page footer ride-up
- Error state now uses the same max-w-5xl container (no layout jump)

Header actions:
- Replace Trash2 icon with PanelLeftClose for sidebar toggle (less alarming)
- Convert sidebar toggle from outline button with text to ghost icon button
- Add aria-label attributes for accessibility
- Tighten gap from gap-2 to gap-1.5 for compact icon-button row
- Move statusBadge/headerActions above the error early-return so both
  code paths share the same header

Chart cards (ActivityChart, TopRegionsChart, DistributionDonut):
- Replace raw rounded-2xl border divs with shadcn Card/CardHeader/CardContent
- Picks up consistent rounded-lg, bg-card, shadow-sm, and standard padding

List cards (ParticipantsList, RecentActivityList):
- Normalize from rounded-2xl to rounded-lg with bg-card and shadow-sm
- Preserve overflow-hidden and custom internal grid layouts

Skeleton:
- Add tabs placeholder skeleton
- Use Card/CardHeader/CardContent for chart skeletons
- Normalize table skeleton wrapper to match new card styles

Tabs:
- Add bg-muted/50 to TabsList for subtle visual grounding
2026-05-18 14:14:32 -03:00
lemon 9905d39e19 Redesign communities landing page 2026-05-18 10:14:21 -07:00
lemon e91f4a2c63 Move help to account menu 2026-05-18 09:55:18 -07:00
lemon 98976c9ce9 Add search nav link 2026-05-18 09:53:50 -07:00
lemon b1e0bcda63 Add organize nav link 2026-05-18 09:50:53 -07:00
lemon 634e161085 Remove ephemeral geo chat 2026-05-18 09:49:31 -07:00
lemon ae41290b68 Hide blocked campaign 2026-05-18 09:45:30 -07:00
lemon 77b35995eb Align top nav controls 2026-05-18 09:41:59 -07:00
lemon 94bcf23b68 Improve account menu 2026-05-18 09:37:46 -07:00
lemon 847b2f2f00 Update Agora navigation 2026-05-18 09:33:44 -07:00
lemon 1eace996f5 Simplify community tab selector 2026-05-18 00:22:48 -07:00
lemon 9d4116b478 Polish donation success state 2026-05-18 00:20:38 -07:00
lemon c281764bd9 Reuse donation dialog for communities 2026-05-18 00:16:49 -07:00
lemon a3e3202f21 Use review step for community zaps 2026-05-18 00:10:43 -07:00
lemon 09dac639c9 Improve donation review details 2026-05-18 00:01:50 -07:00
lemon b3bdf69d61 Polish community and donation flows 2026-05-17 23:58:31 -07:00
lemon 59fd1b2d14 Make campaign submit full width 2026-05-17 23:12:13 -07:00
lemon de26235621 Remove campaign form subtext 2026-05-17 23:12:13 -07:00
lemon f4f07ce91f Remove empty beneficiary placeholder 2026-05-17 23:12:13 -07:00
lemon 93d00ea4c0 Polish campaign deadline input 2026-05-17 23:12:13 -07:00
lemon 2571f9d216 Polish campaign goal input 2026-05-17 23:12:13 -07:00
lemon f665ffa0c0 Flatten campaign form details 2026-05-17 23:12:13 -07:00
lemon 58ca29fb62 Inline beneficiary notify action 2026-05-17 23:12:13 -07:00
lemon a4e785e574 Use canonical invite links 2026-05-17 23:12:13 -07:00
lemon f3b277bc23 Share campaign recipient invites 2026-05-17 23:12:13 -07:00
lemon 42b901d769 Polish campaign country selector 2026-05-17 23:12:13 -07:00
lemon ba2c541c31 Add country tags to campaigns 2026-05-17 23:12:13 -07:00
Chad Curtis 735de6ece9 Treat Tibet as country-level across post + country chrome
Extends the prior Tibet/CountryFlag work so the Snow Lion flag wins
everywhere a CN-XZ post or page surfaces, not just in the Discover
country pulse strip.

  - Comment context (NoteCard + PostDetailPage)
      * Country pill on the card header swaps in the SVG via
        CountryFlag (was bare emoji span).
      * Pill hover card uses the subdivision's own name, drops the
        parent-country sub-line, and labels it as 'Country' rather
        than 'Region' for codes with a custom flag.
      * CountryFlagBackdrop (the faded full-bleed flag behind a
        country-rooted note) prefers the bundled SVG over the
        Wikipedia lead image, which for Tibet returns an
        administrative map.

  - PostDetailPage 'country above the post' chip
      * CountryPreview now routes through CountryFlag and prefers
        info.subdivisionName when a custom flag is registered, so
        the chip reads as 'Tibet' instead of 'China'.

  - Country page (/i/iso3166:CN-XZ)
      * Hero banner driven by customFlagAsset(code) when present,
        sharing the same <img>+skyOverlay pipeline as Wikipedia
        photos so the day/night tint and bottom fade still apply.
      * Subline beneath the title no longer falls into the
        'subdivision = show parent country' branch for custom-flag
        codes; it now reads the Wikipedia description / official
        name like other countries do.
      * Big flag slot uses CountryFlag too, bypassing the Wikipedia
        subdivision thumbnail.

  - Helpers split out of CountryFlag.tsx into src/lib/customFlags.ts
    (hasCustomFlag, customFlagAsset) so the component file only
    exports a component — fixes the react-refresh warning that came
    out of the first pass.

  - Action cards (feed + detail) now render their country chip
    through CountryFlag, picking up the SVG for any future Tibet-
    tagged action.
2026-05-17 23:39:23 -05:00
Chad Curtis e5f7ece942 Bring back Tibet as a country with Snow Lion flag SVG
The older Pathos/Agora codebase treated CN-XZ as country-level Tibet
with a bundled Wikimedia Snow Lion SVG (commits f03d2400, 351b3be4,
6e04b80d). That fell out somewhere in the port — restore it.

  - public/flag-tibet.svg recovered verbatim from f03d2400.
  - New CountryFlag component centralises the country-flag rendering
    decision: emoji for everyone Unicode covers, bundled SVG for the
    short list of recognised flags that don't have an emoji
    codepoint (Tibet today, room for more later).
  - CountryPulseStrip special-cases CN-XZ as country-level: renders
    'Tibet' (not 'Tibet Autonomous Region, China') and drops the
    XZ subdivision-token badge.

Also adds the subdivisionFlag() helper for RGI tag-sequence
subdivisions (England, Scotland, Wales) — Unicode actually does
ship those, and the strip now picks them up automatically.

Other Unicode-missing subdivisions (US states, Canadian provinces)
still render as parent country flag plus a typographic ISO 3166-2
badge. They have no emoji codepoint and bundling a flag pack for
every state is out of scope for this change.
2026-05-17 23:39:23 -05:00
Chad Curtis 5ebc988190 Narrow /discover content widths
Cap the Discover page at max-w-5xl (down from max-w-7xl) so the
hero, country pulse, and shelves stop sprawling on widescreen
displays. Tighten the mixed feed below to max-w-2xl so each row
reads at a comfortable line length, the same reading column width
as the rest of Agora's NoteCard feeds — while the horizontal
shelves keep their wider canvas above.
2026-05-17 23:39:23 -05:00