diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 517ff00..435fe7b 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -6501,6 +6501,7 @@ walletUi: { supportersTotals: '{{count}} supporters · {{angor}} sats via Angor · {{zap}} sats zapped', quietNote: 'Plus everyone who gave quietly — thank you. ❤️', tiersNote: 'Tiers: Supporter under 100k sats · Patron 100k–1M · Legend 1M+', + tierEmpty: 'No one yet — be the first.', joinSupporters: 'Join {{count}} supporters', showAll: 'Show all {{count}}', showLess: 'Show less', diff --git a/src/i18n/es.ts b/src/i18n/es.ts index d190ea2..4de33e4 100644 --- a/src/i18n/es.ts +++ b/src/i18n/es.ts @@ -6501,6 +6501,7 @@ walletUi: { supportersTotals: '{{count}} patrocinadores · {{angor}} sats vía Angor · {{zap}} sats zapeados', quietNote: 'Y a todos los que aportaron en silencio — gracias. ❤️', tiersNote: 'Niveles: Colaborador menos de 100k sats · Patrón 100k–1M · Leyenda 1M+', + tierEmpty: 'Nadie todavía — sé el primero.', joinSupporters: 'Únete a {{count}} patrocinadores', showAll: 'Ver los {{count}}', showLess: 'Ver menos', diff --git a/src/pages/SupportersPage.tsx b/src/pages/SupportersPage.tsx index 5cbfd5f..d951752 100644 --- a/src/pages/SupportersPage.tsx +++ b/src/pages/SupportersPage.tsx @@ -20,7 +20,7 @@ const ANGOR_PROJECT_URL = 'https://angor.io/project/angor1qtunna00uqyx52rr0nvqa0 // platform zap is already ≥ 2026-01, so this doesn't currently trim the list — // the visible cap below is what keeps it short. const SUPPORTERS_SINCE = Math.floor(Date.UTC(2025, 11, 1) / 1000); // 2025-12-01 -const VISIBLE_LIMIT = 10; +const VISIBLE_LIMIT = 21; // ─── Static data — edit these arrays to add/remove entries ────────────────── @@ -248,11 +248,77 @@ interface SupporterEntry { } const TIER_META = { - supporter: { color: '#22d3ee', key: 'walletUi.supporters.tierSupporter' }, - patron: { color: '#f7931a', key: 'walletUi.supporters.tierPatron' }, - legend: { color: '#facc15', key: 'walletUi.supporters.tierLegend' }, + supporter: { color: '#22d3ee', key: 'walletUi.supporters.tierSupporter', emoji: '🛹' }, + patron: { color: '#f7931a', key: 'walletUi.supporters.tierPatron', emoji: '🔥' }, + legend: { color: '#facc15', key: 'walletUi.supporters.tierLegend', emoji: '👑💎✨' }, } as const; +const TIER_ORDER = ['legend', 'patron', 'supporter'] as const; +const TIER_RANGE: Record<(typeof TIER_ORDER)[number], string> = { + legend: '1M+', + patron: '100k–1M', + supporter: '< 100k', +}; + +function MemberAvatar({ entry }: { entry: SupporterEntry }) { + const { data } = useAuthor(entry.anonymous ? undefined : entry.npub); + const meta = data?.metadata; + const name = entry.anonymous + ? '★' + : entry.name || meta?.display_name || meta?.name || entry.npub || ''; + const avatar = entry.anonymous ? undefined : (entry.logo || meta?.picture); + return ( + + {avatar && } + + {entry.anonymous ? '🛹' : name.replace(/[^a-zA-Z0-9]/g, '').charAt(0).toUpperCase() || 'S'} + + + ); +} + +function TierLadder({ supporters }: { supporters: SupporterEntry[] }) { + const { t } = useTranslation(); + return ( +
+ {TIER_ORDER.map((tier) => { + const meta = TIER_META[tier]; + const members = supporters.filter((s) => tierOf(s.sats) === tier); + return ( +
+
+ + {meta.emoji} {t(meta.key)} + + {TIER_RANGE[tier]} +
+ {members.length > 0 ? ( +
+ {members.slice(0, 10).map((m) => ( + + ))} + {members.length > 10 && ( + +{members.length - 10} + )} +
+ ) : ( +

{t('walletUi.supporters.tierEmpty')}

+ )} +
+ ); + })} +
+ ); +} + function SupporterRow({ rank, entry }: { rank: number; entry: SupporterEntry }) { const { t } = useTranslation(); const { data } = useAuthor(entry.anonymous ? undefined : entry.npub); @@ -262,7 +328,7 @@ function SupporterRow({ rank, entry }: { rank: number; entry: SupporterEntry }) : entry.name || meta?.display_name || meta?.name || (entry.npub ? `${entry.npub.slice(0, 12)}…${entry.npub.slice(-6)}` : t('walletUi.supporters.anonymousBacker')); const avatar = entry.anonymous ? undefined : (entry.logo || meta?.picture); - const tier = TIER_META[tierOf(entry.angorSats || undefined)]; + const tier = TIER_META[tierOf(entry.sats)]; const profileHref = !entry.anonymous && entry.npub ? `/${entry.npub}` : undefined; const linkHref = profileHref || entry.url; const proofUrl = entry.txid @@ -301,14 +367,17 @@ function SupporterRow({ rank, entry }: { rank: number; entry: SupporterEntry }) {entry.zap && }
- {entry.angor && ( - - {t(tier.key)} - - )} + = 1_000_000 ? `0 0 10px ${tier.color}66` : undefined, + }} + > + {tier.emoji} {t(tier.key)} + {entry.note && !entry.anonymous && {entry.note}}
@@ -589,9 +658,7 @@ export default function SupportersPage() {

{t('walletUi.supporters.quietNote')}

-

- {t('walletUi.supporters.tiersNote')} -

+ ) : (