feat: add claimable revenue section and claim UI to contributor dashboard (closes #589) - #862
feat: add claimable revenue section and claim UI to contributor dashboard (closes #589)#862Cyber-Mitch wants to merge 2 commits into
Conversation
|
@Cyber-Mitch Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
Auto-review failed (API error). Leaving PR for human review. |
|
Auto-review failed (API error). Leaving PR for human review. |
davidmaronio
left a comment
There was a problem hiding this comment.
this is a strong feature PR. the component reuses the canonical claimable computation from useContributions instead of inventing a new data source, the tx lifecycle phases drive the button label, sibling claim buttons are disabled while one claim is in flight, and the test suite covers rendering, filtering, success, failure, empty, loading, error, and the in-flight disable. typecheck, build, and unit tests are all green.
on the overlap question: #691 is a claim-all button for refunds in MyContributionsSection, different feature and different files, so these do not conflict and both can land.
asks before merge:
- branch name: the "Validate branch name" check fails, and that one is a real failure, not the stale-base issue. this likely means opening a fresh PR from a conventionally named branch or renaming the branch per CONTRIBUTING.md.
- src/components/ClaimableRevenueSection.tsx:299 onward - all user-facing strings ("Claimable Revenue", "Revenue claimed successfully.", the empty state, "Signing...", etc.) are hardcoded english. the rest of the dashboard goes through next-intl (you already call
useLocalefor number formatting), so please add these to messages/en.json and es.json and useuseTranslations. - src/components/ClaimableRevenueSection.tsx:303 -
showError(parseContractError(err))can surface a raw"ContractErrors.xyz"namespace key; #858 is fixing exactly this pattern elsewhere. once your strings go through next-intl, run the parsed error through the same localization helper. - minor:
aria-label={Claim revenue for ${title}}will also need i18n once item 2 is done.
closes #589
Description
Adds a "Claimable Revenue" section to the contributor dashboard, showing all EducationalStartup campaigns with unclaimed revenue and a one-click Claim button per campaign. Closes #589.
Changes
src/components/ClaimableRevenueSection.tsx(new, ~155 lines) — dashboard section that reads from the existinguseContributionshook, filters tocategory === EducationalStartup && canClaimRevenue && claimable > 0, and renders a card/row per campaign with the campaign title, formatted claimable amount (XLM), a per-row Claim button, and a header total.src/app/[locale]/dashboard/DashboardClient.tsx(modified, +3 lines) — one import + render call to mount the new section at the top of the dashboard.src/__tests__/components/ClaimableRevenueSection.test.tsx(new, 8 tests) — covers rendering, header total, filtering (excludes non-EducationalStartup and zero-claimable rows), success path, empty state, loading state, and sibling-button disabling during an in-flight claim.Recon Notes
claim_creator_revenue, but the actual wired binding in this frontend isclaimRevenue(campaignId, contributor, options?)(src/lib/contractClient.ts:937), which invokes the on-chain methodclaim_revenue. It builds and signs a Soroban transaction through the active wallet signer (Freighter/social login), returns atxHash, throws parsed contract errors, and accepts anonStatuslifecycle callback. No binding changes were needed — naming discrepancy noted for visibility only, not a blocker.useContributions, combining three real contract views —get_contribution,get_revenue_pool,get_revenue_claimed— viaclaimable = (contribution × pool) ÷ .... Reused this existing hook rather than fabricating a new data source.formatAmount(stroops, locale, { maximumFractionDigits: 4 })utility — no new formatter written.Cardcomponent, Tailwind,useToast(showSuccess/showError), React Query for data fetching,useWallet()for signer state.Claim Flow States
Signing…→Confirming…); all claim buttons disable during any in-flight claim (disabled={pendingCampaignId !== null}).showSuccess()toast fires, thenrefetch()— the claimed row's amount recomputes to 0 and drops out of the list without a page reload.showError()— no silent failures.ContributionsSectionpattern. Hook loading and error states are also handled.Blockers
src/components/WalletContext.tsxhas a type gap (WalletContextTypemissingwalletKind/socialProfile/isSocialLoginAvailable/connectWithSocial) that failstsc/the Next build step. This was present in the baseline before this change and is out of scope — fixing it here would be scope creep. My new component compiles cleanly on its own.Test Results
New suite: 8/8 passing.
Full suite: 10 failed / 51 passed (suites), consistent with baseline's 10 pre-existing failing suites — no regressions introduced. +8 new passing tests from this change.
WalletContext.tsx:373error noted above.WalletContext.tsx:373typecheck step, same as baseline.Checklist
ClaimableRevenueSection.tsx:98)ClaimableRevenueSection.tsx)claimRevenue(campaignId, walletAddress, { onStatus })with correct args:56-70handler,:75-79labels,:92-93loading):99-101)git statusshows only the new component, its test, and the 3-line dashboard integration