Skip to content

FT support for campaigns #388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
May 24, 2025

Conversation

akaia-shadowfox
Copy link
Collaborator

@akaia-shadowfox akaia-shadowfox commented May 21, 2025

Summary by CodeRabbit

  • New Features

    • Added support for selecting and displaying different tokens (including USD value) in campaign forms and donation flows.
    • Token selectors now allow hiding zero-balance tokens and displaying token balances in dropdowns.
    • Campaigns and donations now support fungible tokens beyond the native token, with improved token-aware progress bars and settings displays.
    • Introduced a new share button component for donation campaign success on X (Twitter).
  • Improvements

    • Enhanced campaign and donation components to display token symbols, icons, and properly formatted amounts.
    • Donation forms and campaign forms now provide real-time USD approximations for entered amounts.
    • Refined validation and handling of token-related fields in forms.
    • Improved token ID handling and synchronization in donation and campaign forms.
    • Updated donation modal and allocation components to support cached token IDs and refined allocation strategies.
  • Bug Fixes

    • Corrected handling of token IDs and improved synchronization between selected tokens and form state.
    • Improved defaulting and validation logic for campaign and donation token amounts.
  • Refactor

    • Unified and clarified type definitions for tokens and campaign inputs.
    • Renamed and reorganized several functions, types, and components for clarity and consistency.
    • Removed deprecated and unused components and hooks.
    • Updated donation multicall functions with clearer naming and added campaign recipient account handling.
    • Refactored campaign components to use token-aware amount conversions and memoization.
  • Chores

    • Updated spell checker dictionary and added minor style adjustments for UI consistency.

@akaia-shadowfox akaia-shadowfox self-assigned this May 21, 2025
@akaia-shadowfox akaia-shadowfox linked an issue May 21, 2025 that may be closed by this pull request
Copy link

vercel bot commented May 21, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
potlock-next-app ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 24, 2025 2:08am

Copy link
Contributor

coderabbitai bot commented May 21, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This update introduces full support for fungible token (FT) donations to campaigns, including a new multicall function for campaign FT donations, enhanced contract client APIs, and comprehensive refactoring of token handling across campaign and donation components. It also generalizes token display, selection, and validation, and updates related types, schemas, and UI logic.

Changes

File(s) Change Summary
.vscode/settings.json Added "Multicall", "remeda", and "TGAS" to spell checker dictionary.
src/common/contracts/core/campaigns/client.ts, src/common/contracts/core/campaigns/interfaces.ts Added contract config types and methods; updated campaign input types and field naming for consistency.
src/common/contracts/core/donation/client.ts Renamed functions to snake_case; updated parameter and return types for FT support.
src/common/ui/form/components/select.tsx Split and clarified controlled/uncontrolled select field props for type safety.
src/entities/_shared/token/components/inputs.tsx, src/entities/_shared/token/hooks/data.ts, src/entities/_shared/token/index.ts Removed deprecated NEAR input field and USD display hook; updated token module exports.
src/entities/_shared/token/components/selector.tsx Added balance display and zero-balance filtering to token selector and options.
src/entities/campaign/components/CampaignBanner.tsx, src/entities/campaign/components/CampaignCard.tsx, src/entities/campaign/components/CampaignCarouselItem.tsx, src/entities/campaign/components/CampaignDonorsTable.tsx, src/entities/campaign/components/CampaignSettings.tsx Refactored to use generic token handling, dynamic token icons, and floating-point conversions for campaign amounts.
src/entities/campaign/components/CampaignForm.tsx Added token selection and USD value display to campaign form monetary fields.
src/entities/campaign/components/CampaignProgressBar.tsx Refactored to support arbitrary tokens, decimals, and dynamic token icons.
src/entities/campaign/components/CampaignDonationItem.tsx Deleted donation item component.
src/entities/campaign/hooks/forms.ts Improved form logic for new/existing campaigns, token-aware validation, and amount conversion.
src/entities/campaign/models/schema.ts Added ft_id schema for token selection in campaigns.
src/entities/voting-round/hooks/vote-weight.ts, src/entities/voting-round/utils/weight.ts Changed defaulting logic for vote weight calculation from ?? to `
src/features/donation/components/group-allocation.tsx, src/features/donation/components/single-recipient-allocation.tsx Passed hideZeroBalanceOptions to token selector in donation allocation forms.
src/features/donation/components/modal-confirmation-screen.tsx Updated allocation strategy logic for single recipient detection.
src/features/donation/components/modal-content.tsx, src/features/donation/components/modal.tsx Updated modal props to include cachedTokenId for donation flows.
src/features/donation/components/single-recipient-success.tsx Refactored token ID computation and UI alignment for donation success screen.
src/features/donation/components/user-entrypoints.tsx Renamed and extended donation-to-campaign entrypoint with cached token support.
src/features/donation/hooks/form.ts, src/features/donation/hooks/user-flow.ts Added support for cached token ID in donation form/user flow hooks; improved token sync logic.
src/features/donation/models/effects/campaign-ft-donation.ts Added campaignFtDonationMulticall for campaign FT donation multicall execution.
src/features/donation/models/effects/direct-ft-donation.ts, src/features/donation/models/effects/group-list-donation.ts, src/features/donation/models/effects/group-pot-donation.ts Renamed multicall types/functions for clarity and consistency.
src/features/donation/models/effects/index.ts Integrated new FT donation multicall logic, updated effect signatures, and improved error handling.
src/features/donation/models/schemas.ts Added campaignRecipientAccountId to donation submit params.
uno.config.ts Added CSS rule to hide .selector-option-appendix in comboboxes.
src/features/donation/components/campaign-success-share.tsx Added new component for sharing campaign donation success on X (Twitter) platform.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI
    participant DonationForm
    participant CampaignsContract
    participant FTContract

    User->>UI: Selects campaign and token, enters amount
    UI->>DonationForm: Submits donation with token info
    DonationForm->>FTContract: Check storage balance, deposit if needed
    DonationForm->>CampaignsContract: Get config (for protocol fee recipient)
    DonationForm->>FTContract: ft_transfer_call (send donation to campaign)
    FTContract-->>CampaignsContract: Triggers on_transfer with donation details
    CampaignsContract-->>DonationForm: Returns donation receipt
    DonationForm-->>UI: Show donation success and updated campaign progress
Loading

Possibly related issues

Possibly related PRs

  • Finalize FT donation flow #366: Also adds multicall logic for campaign FT donations and updates effect usage, directly related to the new multicall function.
  • Campaign Fixes  #357: Updates contract client methods and types, overlapping with changes to campaign contract client APIs in this PR.
  • FT support for campaigns #388: Adds fungible token support for campaigns including contract client methods and types, directly related to campaign FT donation features.

Suggested reviewers

  • carina-akaia
  • Ebube111

Poem

In fields of code where tokens leap,
Campaigns now accept more than NEAR to keep!
With multicalls and types anew,
Balances show, and USD too.
Rabbits hop in UI delight—
FT donations now work just right!
🐇✨

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 51db806 and caf9b6f.

📒 Files selected for processing (1)
  • src/features/donation/components/campaign-success-share.tsx (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@akaia-shadowfox akaia-shadowfox changed the base branch from main to staging May 21, 2025 02:24
@akaia-shadowfox akaia-shadowfox marked this pull request as ready for review May 24, 2025 01:05
@akaia-shadowfox akaia-shadowfox requested a review from Ebube111 as a code owner May 24, 2025 01:05
@akaia-shadowfox akaia-shadowfox removed the request for review from Ebube111 May 24, 2025 01:05
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🔭 Outside diff range comments (1)
src/common/contracts/core/donation/client.ts (1)

47-71: 🛠️ Refactor suggestion

⚠️ Potential issue

Good type safety improvement, but address the empty object type.

The use of IndivisibleUnits type for deposit amounts improves type safety. However, the static analysis correctly flags an issue with the empty object type.

Apply this diff to fix the empty object type:

-export const storage_deposit = (depositAmountYocto: IndivisibleUnits) =>
-  contractApi.call<{}, IndivisibleUnits>("storage_deposit", {
+export const storage_deposit = (depositAmountYocto: IndivisibleUnits) =>
+  contractApi.call<Record<string, never>, IndivisibleUnits>("storage_deposit", {
    deposit: depositAmountYocto,
    args: {},
    gas: "100000000000000",
  });

Using Record<string, never> explicitly indicates an empty object with no properties, which is more precise than the {} type.

🧰 Tools
🪛 Biome (1.9.4)

[error] 67-67: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

🧹 Nitpick comments (7)
src/entities/campaign/components/CampaignSettings.tsx (1)

94-97: Optimize the memoized token icon.

The tokenIcon creates a new React element on every render, which defeats the purpose of memoization. Consider memoizing just the token ID and rendering the icon inline.

-  const tokenIcon = useMemo(
-    () => <TokenIcon tokenId={campaign?.ft_id ?? NATIVE_TOKEN_ID} />,
-    [campaign?.ft_id],
-  );
+  const tokenId = campaign?.ft_id ?? NATIVE_TOKEN_ID;

Then use <TokenIcon tokenId={tokenId} /> directly in the JSX where needed.

src/entities/campaign/components/CampaignForm.tsx (1)

135-145: Remove unnecessary memoization.

The selectedTokenIndicator is always disabled and doesn't depend on any changing values. This memoization adds complexity without benefit.

-  const selectedTokenIndicator = useMemo(
-    () => (
-      <FormField
-        control={form.control}
-        name="ft_id"
-        render={() => <TokenSelector disabled value={ftId} />}
-      />
-    ),
-
-    [form.control, ftId],
-  );

Then inline the JSX directly where it's used:

-  inputExtension={selectedTokenIndicator}
+  inputExtension={<TokenSelector disabled value={ftId} />}
src/features/donation/models/effects/index.ts (1)

145-146: Address TODO: bypass_creator_fee functionality

The bypass_creator_fee is hardcoded to false with TODOs indicating the functionality might be required. This could impact fee collection for campaign creators.

Would you like me to help implement the bypass_creator_fee functionality or create an issue to track this requirement?

Also applies to: 163-164

src/entities/campaign/hooks/forms.ts (1)

183-183: Remove outdated TODO comment.

The TODO comment is no longer relevant as the implementation below correctly uses token metadata for amount conversion.

-  // TODO: Use token metadata to convert amounts
   const onSubmit: SubmitHandler<Values> = useCallback(
src/entities/campaign/components/CampaignProgressBar.tsx (1)

181-192: Optimize memoization dependencies to avoid redundancy.

The dependency array includes both amountDisplay and its constituent values (tokenId, raisedAmountFloat, targetAmountFloat, token?.metadata.symbol), which creates redundancy.

   }, [
     amountDisplay,
     isTimeUp,
     isTargetMet,
-    raisedAmountFloat,
     minAmountFLoat,
     isEscrowBalanceEmpty,
     color,
-    tokenId,
-    targetAmountFloat,
-    token?.metadata.symbol,
   ]);
src/entities/_shared/token/components/selector.tsx (1)

31-31: Optimize balance fetching logic.

Consider simplifying the boolean logic for better readability.

-    balanceCheckAccountId: showBalance || skipIfZeroBalance ? viewer?.accountId : undefined,
+    balanceCheckAccountId: (showBalance || skipIfZeroBalance) ? viewer?.accountId : undefined,
src/features/donation/models/effects/campaign-ft-donation.ts (1)

226-232: Enhance error handling for receipt parsing.

Consider adding more specific error handling for JSON parsing failures.

              try {
                return [JSON.parse(decodedReceipt) as CampaignDonation];
-              } catch {
+              } catch (error) {
+                console.warn("Failed to parse donation receipt:", error);
                return acc;
              }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 706e61f and d33d6e5.

📒 Files selected for processing (37)
  • .vscode/settings.json (3 hunks)
  • src/common/contracts/core/campaigns/client.ts (2 hunks)
  • src/common/contracts/core/campaigns/interfaces.ts (2 hunks)
  • src/common/contracts/core/donation/client.ts (4 hunks)
  • src/common/ui/form/components/select.tsx (1 hunks)
  • src/entities/_shared/token/components/inputs.tsx (0 hunks)
  • src/entities/_shared/token/components/selector.tsx (2 hunks)
  • src/entities/_shared/token/hooks/data.ts (1 hunks)
  • src/entities/_shared/token/index.ts (0 hunks)
  • src/entities/campaign/components/CampaignBanner.tsx (6 hunks)
  • src/entities/campaign/components/CampaignCard.tsx (4 hunks)
  • src/entities/campaign/components/CampaignCarouselItem.tsx (2 hunks)
  • src/entities/campaign/components/CampaignDonationItem.tsx (0 hunks)
  • src/entities/campaign/components/CampaignDonorsTable.tsx (3 hunks)
  • src/entities/campaign/components/CampaignForm.tsx (15 hunks)
  • src/entities/campaign/components/CampaignProgressBar.tsx (3 hunks)
  • src/entities/campaign/components/CampaignSettings.tsx (6 hunks)
  • src/entities/campaign/hooks/forms.ts (7 hunks)
  • src/entities/campaign/models/schema.ts (2 hunks)
  • src/entities/voting-round/hooks/vote-weight.ts (1 hunks)
  • src/entities/voting-round/utils/weight.ts (1 hunks)
  • src/features/donation/components/group-allocation.tsx (1 hunks)
  • src/features/donation/components/modal-confirmation-screen.tsx (4 hunks)
  • src/features/donation/components/modal-content.tsx (2 hunks)
  • src/features/donation/components/modal.tsx (1 hunks)
  • src/features/donation/components/single-recipient-allocation.tsx (5 hunks)
  • src/features/donation/components/single-recipient-success.tsx (2 hunks)
  • src/features/donation/components/user-entrypoints.tsx (2 hunks)
  • src/features/donation/hooks/form.ts (6 hunks)
  • src/features/donation/hooks/user-flow.ts (1 hunks)
  • src/features/donation/models/effects/campaign-ft-donation.ts (1 hunks)
  • src/features/donation/models/effects/direct-ft-donation.ts (1 hunks)
  • src/features/donation/models/effects/group-list-donation.ts (1 hunks)
  • src/features/donation/models/effects/group-pot-donation.ts (2 hunks)
  • src/features/donation/models/effects/index.ts (6 hunks)
  • src/features/donation/models/schemas.ts (1 hunks)
  • uno.config.ts (1 hunks)
💤 Files with no reviewable changes (3)
  • src/entities/_shared/token/index.ts
  • src/entities/campaign/components/CampaignDonationItem.tsx
  • src/entities/_shared/token/components/inputs.tsx
🧰 Additional context used
🧠 Learnings (1)
src/features/donation/models/effects/campaign-ft-donation.ts (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/models/effects/ft.ts:206-239
Timestamp: 2025-04-27T20:33:00.401Z
Learning: The donation FT multicall function in src/features/donation/models/effects/ft.ts is designed to be executed only in browser environments, making browser-only globals like `atob()` acceptable to use.
🧬 Code Graph Analysis (18)
src/features/donation/models/schemas.ts (1)
src/common/types.ts (1)
  • AccountId (40-40)
src/features/donation/components/modal-content.tsx (1)
src/features/donation/hooks/form.ts (1)
  • DonationFormParams (31-36)
src/common/contracts/core/campaigns/client.ts (3)
src/common/contracts/core/donation/client.ts (1)
  • storage_deposit (66-71)
src/common/contracts/core/campaigns/interfaces.ts (1)
  • CampaignsContractConfig (3-12)
src/common/types.ts (1)
  • IndivisibleUnits (82-82)
src/features/donation/components/modal.tsx (1)
src/features/donation/components/modal-content.tsx (1)
  • DonationModalContentProps (23-27)
src/entities/campaign/models/schema.ts (1)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (114-114)
src/features/donation/hooks/user-flow.ts (2)
src/features/donation/types.ts (1)
  • DonationAllocationKey (13-13)
src/features/donation/components/modal.tsx (1)
  • DonationModalProps (16-17)
src/features/donation/components/single-recipient-success.tsx (3)
src/common/contracts/core/donation/interfaces.ts (1)
  • DirectDonation (15-26)
src/common/contracts/core/campaigns/interfaces.ts (1)
  • CampaignDonation (53-69)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (114-114)
src/features/donation/models/effects/group-list-donation.ts (2)
src/features/donation/models/schemas.ts (1)
  • DonationSubmitParams (71-74)
src/common/contracts/core/donation/interfaces.ts (1)
  • DirectDonation (15-26)
src/entities/campaign/components/CampaignDonorsTable.tsx (6)
src/common/types.ts (1)
  • ByCampaignId (118-120)
src/common/contracts/core/campaigns/index.ts (1)
  • campaignsContractHooks (7-7)
src/entities/_shared/token/hooks/data.ts (1)
  • useToken (35-192)
src/common/constants.ts (2)
  • NATIVE_TOKEN_ID (114-114)
  • NATIVE_TOKEN_DECIMALS (115-115)
src/entities/_shared/token/components/icons.tsx (1)
  • TokenIcon (31-57)
src/common/lib/format.ts (1)
  • indivisibleUnitsToFloat (16-20)
src/features/donation/models/effects/direct-ft-donation.ts (2)
src/features/donation/models/schemas.ts (1)
  • DonationSubmitParams (71-74)
src/common/contracts/core/donation/interfaces.ts (1)
  • DirectDonation (15-26)
src/entities/campaign/components/CampaignCarouselItem.tsx (3)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (114-114)
src/common/lib/string.ts (1)
  • truncate (14-22)
src/features/donation/components/user-entrypoints.tsx (1)
  • DonateToCampaign (76-98)
src/features/donation/components/user-entrypoints.tsx (2)
src/common/types.ts (1)
  • ByCampaignId (118-120)
src/features/donation/hooks/user-flow.ts (2)
  • DonationUserFlowProps (12-13)
  • useDonationUserFlow (15-44)
src/entities/campaign/components/CampaignCard.tsx (3)
src/entities/campaign/components/CampaignProgressBar.tsx (1)
  • CampaignProgressBar (24-235)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (114-114)
src/features/donation/components/user-entrypoints.tsx (1)
  • DonateToCampaign (76-98)
src/common/contracts/core/campaigns/interfaces.ts (1)
src/common/types.ts (2)
  • IndivisibleUnits (82-82)
  • TokenId (101-101)
src/common/contracts/core/donation/client.ts (3)
src/common/contracts/core/donation/interfaces.ts (2)
  • DirectDonation (15-26)
  • DirectDonationArgs (28-33)
src/common/contracts/core/campaigns/client.ts (2)
  • donate (70-76)
  • storage_deposit (107-112)
src/common/types.ts (1)
  • IndivisibleUnits (82-82)
src/entities/_shared/token/components/selector.tsx (5)
src/common/types.ts (1)
  • ByTokenId (103-108)
src/common/wallet/hooks.ts (1)
  • useWalletUserSession (14-95)
src/entities/_shared/token/hooks/data.ts (1)
  • useToken (35-192)
src/common/ui/form/components/select.tsx (4)
  • SelectFieldOption (18-18)
  • SelectFieldProps (27-38)
  • ControlledSelectFieldProps (20-23)
  • UncontrolledSelectFieldProps (25-25)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (114-114)
src/features/donation/hooks/form.ts (2)
src/common/types.ts (1)
  • TokenId (101-101)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (114-114)
src/features/donation/models/effects/campaign-ft-donation.ts (10)
src/features/donation/models/schemas.ts (1)
  • DonationSubmitParams (71-74)
src/common/types.ts (1)
  • CampaignId (116-116)
src/common/contracts/core/campaigns/interfaces.ts (1)
  • CampaignDonation (53-69)
src/common/contracts/core/campaigns/index.ts (1)
  • campaignsContractClient (7-7)
src/common/blockchains/near-protocol/index.ts (1)
  • nearProtocolClient (6-6)
src/features/donation/constants.ts (1)
  • DONATION_BASE_STORAGE_DEPOSIT_FLOAT (17-17)
src/common/contracts/tokens/fungible/interfaces.ts (2)
  • FungibleTokenStorageBalance (11-11)
  • FungibleTokenMetadata (1-9)
src/common/lib/format.ts (3)
  • indivisibleUnitsToBigNum (9-10)
  • bigNumToIndivisible (12-13)
  • floatToIndivisible (22-23)
src/common/constants.ts (2)
  • NATIVE_TOKEN_DECIMALS (115-115)
  • FULL_TGAS (134-134)
src/common/blockchains/near-protocol/types.ts (1)
  • InformativeSuccessfulExecutionOutcome (3-5)
🪛 Biome (1.9.4)
src/common/contracts/core/campaigns/client.ts

[error] 22-22: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)


[error] 108-108: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

src/common/contracts/core/donation/client.ts

[error] 67-67: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

src/features/donation/models/effects/campaign-ft-donation.ts

[error] 134-135: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 56-56: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)


[error] 59-59: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

🔇 Additional comments (62)
src/entities/voting-round/utils/weight.ts (1)

88-88:

✅ Verification successful

Potential breaking change: Verify if basicWeight of 0 is a valid value.

The change from nullish coalescing (??) to logical OR (||) means that a basicWeight of 0 will now be treated as 1. This could significantly alter voting weight calculations if 0 was intended to mean "no amplification" or "disabled voting power."

Please verify if basicWeight can legitimately be 0 and whether this change is intentional:


🏁 Script executed:

#!/bin/bash
# Search for basicWeight usage and configurations to understand valid values
echo "=== Searching for basicWeight definitions and usage ==="
rg -A 3 -B 3 "basicWeight"

echo "=== Searching for VotingMechanismConfig type definition ==="
ast-grep --pattern 'interface VotingMechanismConfig {
  $$$
}'

echo "=== Searching for voting round configurations ==="
rg -A 5 -B 5 "VOTING_ROUND_CONFIG"

Length of output: 9000


No behavior change: basicWeight = 0 not used

We’ve verified that:

  • In src/entities/voting-round/types.ts, basicWeight is defined as optional (basicWeight?: number).
  • The only hardcoded config (VOTING_ROUND_CONFIG_MPDAO in model/config.hardcoded.ts) sets basicWeight: 1.
  • There are no occurrences of basicWeight = 0 anywhere in the codebase.

As a result, changing

.mul(basicWeight ?? 1)

to

.mul(basicWeight || 1)

does not alter current behavior. If you later need to allow basicWeight = 0 (to explicitly disable amplification), you can revert to nullish coalescing (basicWeight ?? 1). Otherwise, this change is safe to ship.

src/entities/voting-round/hooks/vote-weight.ts (1)

58-58:

✅ Verification successful

Consistent with utility change but verify the impact on voting logic.

This change mirrors the same operator replacement in the utility file. While consistency is good, the same concern applies: if basicWeight can legitimately be 0, this change could affect voting calculations.

Since this hook is likely used in the UI, please verify:

  1. Whether any existing voting round configurations use basicWeight: 0
  2. The expected behavior when basicWeight is 0
  3. Whether this change aligns with the intended voting mechanism design

🏁 Script executed:

#!/bin/bash
# Check for any hardcoded voting configurations that might use basicWeight: 0
echo "=== Searching for hardcoded voting configurations ==="
rg -A 10 -B 5 "basicWeight.*:.*0"

echo "=== Searching for test cases related to vote weight calculation ==="
rg -A 5 -B 5 "basicWeight.*0|weight.*0" --type ts --type tsx

Length of output: 388


🏁 Script executed:

#!/bin/bash
echo "=== Searching for hardcoded basicWeight: 0 across all files ==="
rg -A5 -B5 'basicWeight.*0'

echo "=== Searching for JSON configs with \"basicWeight\": 0 ==="
rg -A5 -B5 '"basicWeight"\s*:\s*0' -g '*.json'

echo "=== Listing every occurrence of basicWeight ==="
rg -n 'basicWeight'

echo "=== Listing every occurrence of votingRoundConfig ==="
rg -n 'votingRoundConfig'

Length of output: 1948


No existing basicWeight = 0 usage; change is safe

  • Verified across codebase (including JSON and TS files) that no voting configuration sets basicWeight to 0.
  • The only hardcoded default is basicWeight: 1 in src/entities/voting-round/model/config.hardcoded.ts.

Since there are currently no scenarios where basicWeight is 0, switching from ?? 1 to || 1 does not alter any existing behavior.

If in the future you intend to use a basicWeight of 0 to disable vote amplification, you should either revert to ?? 1 or add an explicit check for 0.

.vscode/settings.json (1)

85-85: LGTM: Spell check additions are appropriate.

The new spell check words align well with the project's blockchain focus:

  • "Multicall" for contract call batching
  • "remeda" for the functional programming utility library
  • "TGAS" for tera gas units in NEAR blockchain

Also applies to: 102-102, 113-113

uno.config.ts (1)

200-200: Good UI enhancement for combobox components.

The CSS rule effectively hides appendix elements in combobox contexts, which should improve the user experience in token selectors and similar dropdown components.

src/common/contracts/core/campaigns/interfaces.ts (4)

3-12: Well-structured contract configuration type.

The CampaignsContractConfig type comprehensively captures contract metadata including fees, counts, and administrative details. The type structure aligns well with blockchain contract patterns.


43-43: Field reordering is acceptable.

Moving escrow_balance after max_amount doesn't affect functionality and may improve logical grouping of related fields.


20-22:

✅ Verification successful

Type change improves blockchain precision but verify compatibility.

Changing amount fields from number to IndivisibleUnits is necessary for accurate token handling in blockchain contexts, as JavaScript numbers lose precision with large values.

Verify that all existing code using these fields has been updated to handle IndivisibleUnits (string) instead of number:


🏁 Script executed:

#!/bin/bash
# Description: Find usages of campaign amount fields to verify type compatibility
# Expected: All usages should handle IndivisibleUnits (string) type

echo "Searching for target_amount usages..."
rg -A 3 -B 3 "target_amount" --type ts --type tsx

echo "Searching for min_amount usages..."
rg -A 3 -B 3 "min_amount" --type ts --type tsx

echo "Searching for max_amount usages..."
rg -A 3 -B 3 "max_amount" --type ts --type tsx

Length of output: 470


Let’s broaden the search to include both .ts and .tsx files (the sandbox’s rg --type tsx isn’t available):


🏁 Script executed:

#!/bin/bash
# Description: Find usages of campaign amount fields using glob patterns
echo "Searching for target_amount usages..."
rg -n --glob '*.ts' --glob '*.tsx' -A 3 -B 3 "target_amount"

echo "Searching for min_amount usages..."
rg -n --glob '*.ts' --glob '*.tsx' -A 3 -B 3 "min_amount"

echo "Searching for max_amount usages..."
rg -n --glob '*.ts' --glob '*.tsx' -A 3 -B 3 "max_amount"

Length of output: 42492


All amount fields updated to use IndivisibleUnits correctly

We’ve verified every reference to target_amount, min_amount, and max_amount now uses the string-based IndivisibleUnits type with the appropriate conversion utilities:

  • Form handling:
    floatToIndivisible(...) in hooks/forms.ts when submitting
    yoctoNearToFloat(...) in CampaignForm.tsx for populating fields
  • Display components:
    indivisibleUnitsToFloat(...) in CampaignSettings.tsx, CampaignBanner.tsx, and CampaignProgressBar.tsx
  • Props and comparisons:
    – All UI components accept the string values (e.g. data?.target_amount ?? "0") and only compare or render after parsing or conversion

No raw numeric operations remain on the contract-level fields.


39-39:

✅ Verification successful

Field rename improves consistency but verify all references updated.

The rename from ftId to ft_id aligns with the snake_case convention used throughout the contract interfaces.

Verify that all code references to ftId have been updated to use ft_id:


🏁 Script executed:

#!/bin/bash
# Description: Check for any remaining ftId references that should be ft_id
# Expected: No references to old ftId field name

echo "Checking for old ftId references..."
rg -i "ftId" --type ts --type tsx

echo "Verifying new ft_id usage..."
rg -A 2 -B 2 "ft_id" --type ts --type tsx

Length of output: 279


🏁 Script executed:

#!/bin/bash
# Re-run without relying on rg’s built-in types to avoid the “unrecognized file type” error
echo "Checking for any remaining ftId references (searching .ts and .tsx files)..."
rg -i "ftId" -g '*.ts' -g '*.tsx'

echo "Verifying all instances use ft_id (searching .ts and .tsx files)..."
rg "ft_id" -g '*.ts' -g '*.tsx'

Length of output: 4542


No remaining ftId property references detected
All contract‐level fields have been renamed to ft_id. The only ftId hits are in:

  • Deprecated components (e.g. src/layout/profile/_deprecated/DonationItem.tsx, PotDonationEntry.tsx)
  • Local bindings or schema helpers (const ftIdSchema, form‐destructured ftId)

None of these refer to the interface field name, so no further changes are needed.

src/features/donation/models/schemas.ts (1)

73-73: Good addition for FT campaign donation support.

The optional campaignRecipientAccountId field appropriately extends the donation parameters to support fungible token campaign donations while maintaining backward compatibility.

src/features/donation/components/group-allocation.tsx (1)

166-166: LGTM! Good UX improvement for token selection.

Adding hideZeroBalanceOptions to the TokenSelector improves the user experience by filtering out tokens with zero balance, making it easier for users to select from available tokens for donations.

src/entities/_shared/token/hooks/data.ts (1)

12-12: LGTM! Good cleanup of deprecated token utilities.

The removal of useTokenUsdDisplayValue and related imports aligns with the broader refactor to consolidate token handling using the comprehensive useToken hook. This reduces code duplication and provides a more consistent API for token operations.

src/features/donation/components/modal-content.tsx (1)

24-24: LGTM! Proper extension of props for token-aware donations.

Adding cachedTokenId to the modal props interface enables support for token-aware donation flows where the token ID is provided by the indexer. The optional nature of this property maintains backward compatibility while enabling the new FT donation functionality.

src/features/donation/models/effects/group-list-donation.ts (2)

12-12: LGTM! Consistent naming improvement.

Renaming ListDonationMulticallInputs to GroupListDonationMulticallInputs improves consistency with the naming pattern used across other donation effect modules, making the codebase more coherent.


17-22: LGTM! Function renaming aligns with module consistency.

Renaming listDonationMulticall to groupListDonationMulticall maintains consistency with other group donation functions in the module while preserving all existing functionality. The function implementation correctly handles batch donations with proper error handling and receipt parsing.

src/features/donation/components/modal.tsx (1)

16-17: LGTM! Type extension for FT support.

The addition of cachedTokenId to DonationModalProps correctly extends the interface to support token-aware donation flows. This change aligns well with the broader FT support implementation.

src/features/donation/components/modal-confirmation-screen.tsx (3)

29-29: LGTM! Appropriate import for allocation strategy.

The import of DonationAllocationStrategyEnum is necessary for the updated logic that determines donation type based on allocation strategy.


41-49: Excellent refactor to use allocation strategy.

The change from watching recipientAccountId to allocationStrategy and updating the logic to use DonationAllocationStrategyEnum.full is a more robust approach. This determines donation type based on the actual allocation strategy rather than derived state, which improves maintainability and correctness.


92-106: LGTM! Consistent updates to conditional rendering.

The updates to use isSingleRecipientDonation instead of isSingleProjectDonation are consistent with the logic refactoring and maintain the same UI behavior while being based on more reliable state.

Also applies to: 157-192

src/features/donation/hooks/user-flow.ts (2)

9-9: LGTM! Appropriate import extension.

Adding DonationModalProps to the import is necessary for the new type definition.


12-15: Excellent type design for FT support.

The new DonationUserFlowProps type effectively combines the existing DonationAllocationKey with an optional cachedTokenId from DonationModalProps. This approach:

  • Maintains backwards compatibility
  • Uses TypeScript's Pick utility type appropriately
  • Enables token-aware donation flows

The updated hook parameter type properly supports the enhanced functionality.

src/features/donation/components/single-recipient-success.tsx (2)

83-89: Excellent refactor with improved token ID logic.

The useMemo refactor provides several benefits:

  • Performance: Memoizes the computation to prevent unnecessary recalculations
  • Readability: More explicit logic flow compared to the previous inline conditional
  • Correctness: Properly uses ft_id property which aligns with the contract interfaces (as seen in DirectDonation and CampaignDonation interfaces from relevant snippets)

The logic correctly handles different donation types and falls back to NATIVE_TOKEN_ID appropriately.


169-169: LGTM! Minor CSS improvement.

The addition of items-center class improves the flex container alignment for the donation recipient information.

src/entities/campaign/models/schema.ts (2)

56-59: Well-designed FT token validation schema.

The ftIdSchema properly validates fungible token IDs by accepting either the native NEAR token or contract account IDs with a minimum length requirement. The default to NATIVE_TOKEN_ID ensures backward compatibility.


68-68: Good integration of FT ID into campaign schema.

Adding ft_id as a required field with proper validation aligns well with the broader FT support implementation across the codebase.

src/features/donation/models/effects/group-pot-donation.ts (1)

9-9: Good refactoring for naming consistency.

The rename from PotDonationMulticallInputs to GroupPotDonationMulticallInputs and potGroupDonationMulticall to groupPotDonationMulticall improves naming consistency across the donation effects modules.

Also applies to: 18-25

src/entities/campaign/components/CampaignCard.tsx (3)

4-4: Excellent integration of FT token support.

The addition of NATIVE_TOKEN_ID fallback for data.ft_id provides good backward compatibility while enabling fungible token support. Passing the tokenId to CampaignProgressBar and cachedTokenId to DonateToCampaign allows these components to handle token-specific logic appropriately.

Also applies to: 68-68, 79-79


70-72: Good approach: passing raw amounts for token-aware conversion.

Passing raw string amounts (total_raised_amount, min_amount, target_amount) instead of pre-converted values allows the CampaignProgressBar component to perform conversions based on the specific token's decimal precision, which is more accurate and flexible.


25-25: Improved layout flexibility.

Changing from fixed height h-144 to minimum height min-h-144 provides better responsive behavior for cards with varying content lengths.

src/entities/campaign/components/CampaignDonorsTable.tsx (2)

6-6: LGTM! Clean import additions for token generalization.

The new imports support the migration from NEAR-specific handling to generic token support, which aligns perfectly with the PR's FT support objectives.

Also applies to: 8-8, 12-12


56-65: Excellent token-aware amount display implementation.

The dynamic token handling is well-implemented:

  • Proper fallback to NATIVE_TOKEN_ID when campaign?.ft_id is undefined
  • Correct use of token decimals with fallback to NATIVE_TOKEN_DECIMALS
  • Clean integration of TokenIcon component

The vertical alignment styling with pb-1.5 on the icon ensures consistent visual presentation.

src/features/donation/models/effects/direct-ft-donation.ts (1)

19-19: LGTM! Clear and consistent renaming for better code organization.

The renaming from FtDonationMulticallInputs to DirectFtDonationMulticallInputs and ftDonationMulticall to directFtDonationMulticall improves clarity by explicitly indicating this handles direct FT donations. This aligns with the broader refactor mentioned in the AI summary to distinguish different donation flow types.

Also applies to: 24-24, 31-31

src/features/donation/components/single-recipient-allocation.tsx (4)

8-8: LGTM! Consistent variable naming and safer number parsing.

Good improvements:

  • Adding parseNumber import for safer number parsing
  • Renaming viewer to walletUser for consistency across the codebase
  • Updating all references to use the new variable name

Also applies to: 39-39, 50-50


70-72: Verify the FT selector disabling logic for campaign donations.

The logic now always disables FT selection for campaign donations (isCampaignDonation ? false). This seems intentional but differs from the previous behavior mentioned in the AI summary.

Could you clarify the reasoning for always disabling FT selection for campaign donations? Is this because campaigns have a predefined token (via ft_id) that shouldn't be changeable during donation?


74-81: Excellent memoized USD value calculation with safe parsing.

The implementation correctly:

  • Uses useMemo for performance optimization
  • Safely parses the amount with parseNumber before calculation
  • Handles undefined USD price gracefully
  • Provides proper dependency array

This is a significant improvement over direct calculations.


178-215: Great UX improvement with loading skeleton and enhanced token selector.

The conditional rendering provides better user experience:

  • Loading skeleton prevents layout shift during campaign data loading
  • hideZeroBalanceOptions prop improves token selection UX
  • Proper form field structure maintained

The implementation is clean and follows React patterns well.

src/features/donation/components/user-entrypoints.tsx (1)

69-74: LGTM! Clean refactor to support cached token IDs in donation flow.

The changes are well-structured:

  • Type renaming from DonationToCampaignProjectsProps to DonationToCampaignProps is more concise
  • Addition of cachedTokenId support via proper type picking from DonationUserFlowProps
  • Component renaming and prop destructuring updated consistently
  • Hook call properly passes both campaignId and cachedTokenId

This integrates well with the broader token-aware donation flow enhancements mentioned in the AI summary.

Also applies to: 76-77, 83-83

src/entities/campaign/components/CampaignCarouselItem.tsx (2)

4-11: Import changes look good!

The migration to use NATIVE_TOKEN_ID constant and the updated donation component import align well with the FT support objectives.


65-82: Token handling implementation is correct.

The changes properly implement:

  • Token ID propagation with appropriate fallback to NATIVE_TOKEN_ID
  • Raw amount values as strings, consistent with IndivisibleUnits type usage
  • Proper prop passing to both CampaignProgressBar and DonateToCampaign
src/common/ui/form/components/select.tsx (1)

20-38: Excellent type safety improvement!

The separation of controlled and uncontrolled prop types using a discriminated union prevents common React anti-patterns where controlled and uncontrolled props are mixed. This will help catch errors at compile time.

src/common/contracts/core/donation/client.ts (1)

30-36: Naming convention update aligns with contract standards.

The change from camelCase to snake_case for function names matches NEAR contract conventions, ensuring consistency between the client and contract APIs.

src/entities/campaign/components/CampaignSettings.tsx (1)

67-92:

✅ Verification successful

Consider potential floating-point precision issues.

The floating-point conversions might lose precision for very large token amounts. While indivisibleUnitsToFloat likely handles this internally, ensure that the display values are accurate for tokens with high decimal places.


🏁 Script executed:

#!/bin/bash
# Description: Check if indivisibleUnitsToFloat handles precision correctly
# Look for the implementation to verify precision handling
ast-grep --pattern 'function indivisibleUnitsToFloat($_) {
  $$$
}'
rg -A 10 'export.*indivisibleUnitsToFloat'

Length of output: 875


Consider JavaScript number precision limits for large token amounts.

The indivisibleUnitsToFloat helper uses Big’s toFixed(fracDigits ?? 2, 3) to round accurately, but then returns a native JS number via parseFloat. Values with integer parts ≥ Number.MAX_SAFE_INTEGER (≈ 9e15) can’t be represented exactly in a JS number, leading to precision loss for very large balances. If you anticipate amounts that large:

  • Display the string output from toFixed directly instead of converting to a number.
  • Or keep the value as a Big instance until rendering.

This ensures correct display even for tokens with high decimal places and extremely large amounts.

src/features/donation/hooks/form.ts (2)

31-36: LGTM! Well-documented parameter addition.

The cachedTokenId parameter is properly documented and provides a clean way to pre-populate the token selection from external sources like the indexer.


228-239: Token synchronization logic looks solid.

The effect correctly ensures that campaign donations use the campaign's specified token and prevents unnecessary re-renders by checking if the token differs before updating.

src/entities/campaign/components/CampaignForm.tsx (1)

271-295: Token selector integration looks good.

The implementation properly integrates token selection with the amount input field, providing a clean UX for selecting tokens while entering amounts.

src/features/donation/models/effects/index.ts (3)

12-17: LGTM! Import names are more descriptive.

The updated import names clearly indicate the specific donation type each multicall handles, improving code maintainability.


133-137: Good validation for required campaign recipient.

The early validation ensures that FT donations to campaigns have the required recipient account ID, preventing runtime errors.


139-154: Campaign FT donation implementation looks good.

The implementation correctly handles FT donations to campaigns with proper error handling and follows the established pattern.

src/entities/campaign/hooks/forms.ts (4)

38-51: Good use of memoization for parsed amounts.

The memoized parsing ensures consistent number handling and prevents unnecessary recalculations, improving performance.


53-72: Robust token handling in form state.

The disabled state correctly accounts for token loading and validates token availability only for non-native tokens, preventing form submission with invalid token selections.


189-214: Excellent token-aware amount conversion.

The implementation correctly handles amount conversion using token decimals with appropriate fallbacks and conditional inclusion of optional fields.


305-305: Clean simplification of return value.

Returning only self as the form property is cleaner and avoids redundant spreading since the form object already contains all necessary state.

src/entities/campaign/components/CampaignProgressBar.tsx (2)

34-53: Robust token data handling with safe conversions.

The implementation correctly handles undefined token data and consistently converts indivisible units to float values with proper decimal handling.


65-68: Good defensive programming against division by zero.

The code correctly guards against division by zero by using (targetAmountFloat || 1), preventing runtime errors when the target amount is not set.

Also applies to: 206-209

src/entities/_shared/token/components/selector.tsx (2)

17-26: LGTM! Well-designed component enhancement.

The new props for conditional balance display and zero-balance filtering are well-thought-out and provide good UX control.


38-38: Clever UX enhancement with CSS ordering.

The use of CSS order property to prioritize tokens with positive balances is an elegant solution that improves user experience by surfacing available tokens first.

src/features/donation/models/effects/campaign-ft-donation.ts (2)

219-221: Browser-only function usage is acceptable.

The use of atob() is appropriate here as this function is designed to run in browser environments only, consistent with other donation effects.


24-243: Complex but well-structured multicall function.

The function correctly handles all the necessary steps for FT campaign donations:

  1. Fetches protocol config and token metadata
  2. Calculates storage requirements
  3. Ensures adequate storage deposits for all parties
  4. Executes the FT transfer with proper parameters
  5. Extracts and validates the donation receipt

The logic flow is comprehensive and handles edge cases appropriately.

🧰 Tools
🪛 Biome (1.9.4)

[error] 134-135: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 56-56: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)


[error] 59-59: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

src/entities/campaign/components/CampaignBanner.tsx (5)

36-36: Good fallback to native token.

The fallback to NATIVE_TOKEN_ID when campaign?.ft_id is undefined ensures the component works correctly for both FT and native token campaigns.


38-54: Excellent memoization of calculated values.

The memoized calculations for raisedAmountFloat and minAmountFLoat are well-implemented with proper dependencies. This prevents unnecessary recalculations and improves performance.


73-80: Improved USD approximation calculation.

The replacement of the deprecated useTokenUsdDisplayValue hook with a direct memoized calculation is a good improvement that provides more control and clarity.


148-148: Dynamic token symbol display.

The updated amount display using token?.metadata.symbol correctly adapts to different token types, enhancing the user experience for FT campaigns.


214-221: Updated donation component integration.

The replacement of DonateToCampaignProjects with DonateToCampaign and the addition of cachedTokenId prop properly integrates with the enhanced token selection functionality.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/features/donation/components/campaign-success-share.tsx (2)

66-74: Consider breaking down the useMemo dependencies.

The dependency array is quite long, which suggests the memoized logic might be doing too much. Consider splitting this into smaller, more focused useMemo hooks.

Example approach:

+  const recipientReference = useMemo(() => {
+    // Extract recipient reference logic here
+  }, [recipientSocialProfile?.linktree?.twitter, recipientSocialProfile?.name, recipientAccountId]);
+  
+  const shareUrl = useMemo(() => {
+    // Extract URL construction logic here  
+  }, [campaignId, viewer.accountId, viewer.isSignedIn]);
+  
   const intent = useMemo(() => {
-    // Move text and final URL construction here
+    // Simplified intent construction using the above values
-  }, [
-    campaignId,
-    campaignName, 
-    // ... all current dependencies
-  ]);
+  }, [campaignName, recipientReference, shareUrl]);

79-84: Enhance accessibility for the share button.

Consider adding accessibility attributes to improve screen reader support.

-    <Button asChild variant="standard-filled" className="bg-neutral-950 py-1.5 shadow-none">
-      <Link href={intent} target="_blank">
+    <Button asChild variant="standard-filled" className="bg-neutral-950 py-1.5 shadow-none">
+      <Link 
+        href={intent} 
+        target="_blank"
+        rel="noopener noreferrer"
+        aria-label={`Share ${campaignName} campaign on X`}
+      >
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d33d6e5 and 51db806.

📒 Files selected for processing (3)
  • src/entities/campaign/components/CampaignProgressBar.tsx (3 hunks)
  • src/features/donation/components/campaign-success-share.tsx (1 hunks)
  • src/features/donation/components/single-recipient-success.tsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/features/donation/components/single-recipient-success.tsx
  • src/entities/campaign/components/CampaignProgressBar.tsx
🔇 Additional comments (4)
src/features/donation/components/campaign-success-share.tsx (4)

1-18: LGTM! Clean import structure.

The imports are well-organized with appropriate groupings and all necessary dependencies are included.


19-27: LGTM! Well-typed component interface.

The props type definition is clear and uses proper type extraction with Campaign["name"]. The component declaration follows React best practices.


28-31: LGTM! Proper hook usage.

The wallet session and social profile hooks are used correctly with appropriate destructuring and variable naming.


44-65: LGTM! Proper URL construction and encoding.

The share intent URL is constructed correctly with proper encoding of all parameters. The logic for conditional referrer parameter is well-implemented.

@akaia-shadowfox akaia-shadowfox merged commit 44c3c07 into staging May 24, 2025
1 of 5 checks passed
@akaia-shadowfox akaia-shadowfox deleted the 375-campaigns-campaign-ft-donation-support branch May 24, 2025 02:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[CAMPAIGNS] Campaign FT donation support
1 participant