Skip to content

Comments

Staging to main#424

Open
Ebube111 wants to merge 302 commits intomainfrom
staging
Open

Staging to main#424
Ebube111 wants to merge 302 commits intomainfrom
staging

Conversation

@Ebube111
Copy link
Collaborator

@Ebube111 Ebube111 commented Jul 1, 2025

Summary by CodeRabbit

  • New Features

    • Rich text editor with toolbar & character count; additional NEAR wallet options; post-card loading skeletons.
  • Enhancements

    • Campaign descriptions now render HTML with multiline clamp; description max length increased to 500.
    • Live-updating profile images; granular add/update/remove for funding sources, contracts, and repositories.
    • Status-based campaign filtering and progress; donation fee recipients show profile links.
    • SEO-friendly campaign pages plus dynamic sitemap and robots.txt.
  • Bug Fixes

    • Prevented link clicks inside descriptions from triggering navigation; referral fee checkbox display logic adjusted.
  • Chores

    • Package renamed and dependencies updated.

@vercel
Copy link

vercel bot commented Jul 1, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
potlock-next-app Ready Ready Preview, Comment Feb 19, 2026 4:52pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 1, 2025

Important

Review skipped

Too many files!

This PR contains 230 files, which is 80 over the limit of 150.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Switches campaign data to a new indexer API and staging config, adds TipTap rich-text editor and NEAR wallet selector modules, extends campaign creation with optional project multicall, introduces utilities (truncateHtml, toTimestamp, stripHtml), and adds sitemap/robots and loading skeletons across UI.

Changes

Cohort / File(s) Change Summary
Package & Wallets
package.json, src/common/blockchains/near-protocol/client.ts
Package renamed/version bumped; added TipTap deps and Intear/Unity wallet selector modules; integrated wallet modules into walletSelectorModules.
App metadata & banner
src/common/constants.ts
Import package.json to export FRAMEWORK_VERSION; add other: { version } to APP_METADATA; append ASCII banner console.info.
String & datetime utilities
src/common/lib/string.ts, src/common/lib/datetime.ts
Removed extractFromUrl; added truncate, truncateHtml, isValidHttpUrl, toTimestamp, and stripHtml.
Rich text editor UI
src/common/ui/form/components/richtext.tsx, src/common/ui/form/components/index.ts
New TipTap-based RichTextEditor (debounced onChange, toolbar, max-length); exported from form components barrel.
Profile live updates & account UI
src/entities/_shared/account/components/profile-images.tsx, src/entities/_shared/account/components/card.tsx, src/entities/_shared/account/components/AccountProfileLink.tsx
Add live flag to profile image hooks/props; use .url for avatar/cover; change name rendering to CSS ellipsis with title; AccountCard passes live.
Indexer API & staging config
src/common/api/indexer/internal/client.generated.ts, src/common/api/indexer/internal/config.ts, src/common/api/indexer/hooks.ts
Add campaign/donation models and generated indexer endpoints/hooks; add INDEXER_CLIENT_CONFIG_STAGING; expose useCampaigns/useCampaign.
Campaign inputs & contract client
src/common/contracts/core/campaigns/interfaces.ts, src/common/contracts/core/campaigns/client.ts
Extend CampaignInputs with project_name/project_description/project_banner_image_url; create_campaign conditionally builds a multicall (set profile + register project + create_campaign) when project metadata present and recipient==owner.
Campaign components & hooks
src/entities/campaign/components/*, src/entities/campaign/hooks/*, src/entities/campaign/models/schema.ts, src/entities/campaign/utils/constants.ts
Migrate components to indexer shapes (on_chain_id, token.account, net_raised_amount, start_at/end_attoTimestamp), render descriptions as HTML (stopPropagation on links), replace isStarted/isEnded with status, revamp CampaignProgressBar geometry/labels, increase description max to 500, add CAMPAIGN_STATUS_OPTIONS.
Pages & routing (campaigns) + SEO
src/pages/campaigns.tsx, src/pages/campaign/[campaignId]/*.tsx, src/pages/profile/[accountId]/campaigns.tsx, src/pages/index.tsx
Switch pages to indexer hooks (results payload), use on_chain_id for keys/paths, add SSG (getStaticPaths/getStaticProps) and RootLayout-based SEO props on campaign pages, adjust loading UI (Spinner/Skeletons), add FeaturedCampaigns gating by ENV_TAG.
Profile configuration & forms
src/features/profile-configuration/components/*, src/features/profile-configuration/hooks/forms.ts
Add granular add/update/remove handlers for repositories, funding sources, smart contracts; wire handlers to modals/tables; migrate funding source form init to useEnhancedForm; disable smart-contract edit modal.
Repositories UI & util
src/features/profile-configuration/components/repositories-section.tsx
Add extractRepositoryPath, per-repo local input state to preserve focus, onBlur canonicalization, and per-repo remove button.
Funding sources & contracts UI
src/features/profile-configuration/components/AddFundingSourceModal.tsx, funding-sources.tsx, contracts-section.tsx, editor.tsx
Expose onAddFundingSource/onUpdateFundingSource, add onDeleteClick for funding table, and replace edit-modal flows with explicit add/remove handlers for contracts and funding sources.
Donation UI
src/features/donation/components/modal-confirmation-screen.tsx, src/features/donation/components/summary.tsx, src/features/donation/hooks/allocation.ts
Referral bypass checkbox gating simplified (now only checks referral fee > 0); DonationSummary shows fee recipient AccountProfileLink when present; allocation hook prefers campaign-specific config via campaignsContractHooks.useConfig.
Post feed & skeletons
src/entities/post/components/PostCard.tsx, src/entities/post/components/PostCardSkeleton.tsx, src/entities/post/index.ts, src/pages/feed/index.tsx
Visual refactor of PostCard; add PostCardSkeleton (exported) and use skeletons in feed loading/initial states.
Layout & small UI tweaks
src/layout/profile/components/summary.tsx, src/layout/components/project-discovery.tsx, src/common/ui/layout/components/atoms/progress.tsx, src/layout/campaign/components/layout.tsx, src/layout/components/root-layout.tsx, src/layout/components/app-bar.tsx
Show centered Spinner while profile loads; better empty-state placement; center MIN arrow using translateX(-50%); add Link prefetch for campaign tabs; RootLayout meta defaults to APP_METADATA; always-enable Campaigns app-bar link.
Sitemap & robots
src/pages/sitemap.xml.ts, src/pages/robots.txt.ts
Add dynamic sitemap.xml and robots.txt server handlers that fetch campaign/list data and serve XML/plain text with caching headers.
Misc UI & hooks
src/common/contracts/core/campaigns/hooks.ts, src/common/_config/production.env-config.ts, src/common/ui/form/components/index.ts
Add useConfig hook for campaign contract config; update production campaigns contract accountId to staging-prefixed value; export richtext from form components index.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CampaignEditor
  participant RichTextEditor
  participant FormState
  participant ContractClient

  User->>CampaignEditor: open create editor
  CampaignEditor->>RichTextEditor: mount value/placeholder
  User->>RichTextEditor: edit content (HTML)
  RichTextEditor->>FormState: debounced onChange (HTML)
  FormState-->>CampaignEditor: updated form values (may include project_name/description)
  CampaignEditor->>ContractClient: submit create_campaign(args)
Loading
sequenceDiagram
  participant Caller
  participant create_campaign
  participant Multicall

  alt project_name present && recipient == owner
    Caller->>create_campaign: args with project_name/project_description
    create_campaign->>Multicall: set_profile + register_project + create_campaign (batch)
    Multicall-->>create_campaign: tx results
    create_campaign-->>Caller: success
  else
    Caller->>create_campaign: args (no project metadata)
    create_campaign-->>Caller: single create tx
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Prometheo
  • Jikugodwill
  • carina-akaia

Poem

"I nibble code with twitching nose and cheer,
TipTap blooms where links and text appear.
Campaigns march on with statuses and flair,
Live avatars shimmer—soft fur in the air.
Skeletons cradle the feed as it wakes." 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title "Staging to main" accurately indicates a branch merge but is too generic and does not describe the substantive changes in this PR (e.g., switching to the indexer API and campaign model, adding TipTap rich-text editor and wallet selector deps, SSG for campaign pages, sitemap/robots, and many UI/logic refactors), so it won’t help a reviewer quickly understand the primary intent. Please update the title to a concise, descriptive summary of the primary changes; for example: "Migrate to indexer API & campaign model, add campaign SSG + sitemap, RichText editor (TipTap) and wallet-selector deps (#424)". A short title that names the main scope (data-source migration, campaign refactor, or feature added) will make the PR easier to review and the history easier to scan.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch staging

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

Comment @coderabbitai help to get the list of available commands and usage tips.

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: 10

🔭 Outside diff range comments (2)
src/features/profile-configuration/components/contract-modal.tsx (1)

61-66: Implement missing smart contract dispatch in ContractModal

The commented-out dispatch block in src/features/profile-configuration/components/contract-modal.tsx (around lines 61–66) must be restored—or replaced with the correct action—to persist changes to the store. Without this, selecting a chain/address won’t update the application state and “Save” will have no effect.

• File: src/features/profile-configuration/components/contract-modal.tsx
• Location: ~lines 61–66

Suggested diff:

-   // TODO: Don't forget to rewrite
-   // Update contract info in the store
-   // dispatch.projectEditor.editSmartContract({
-   //   data: [chain, address],
-   //   contractIndex,
-   // });
+   // Update contract info in the store
+   dispatch.profileConfiguration.editSmartContract({
+     data: [chain, address],
+     contractIndex,
+   });

—or, if your slice is named differently (e.g. projectEditor), adjust the dispatch path to match your current store setup.

src/features/profile-configuration/components/repositories-section.tsx (1)

61-86: Address commented-out code and incomplete functionality.

Most of the component's change handling logic is commented out, and the current implementation uses an empty function for the onChangeHandler. This suggests the component is in an incomplete state.

Consider either:

  1. Implementing the missing change handler functionality
  2. Removing the commented code if it's no longer needed
  3. Adding a TODO comment explaining the incomplete state

The component currently renders but doesn't handle user interactions properly.

♻️ Duplicate comments (1)
src/features/profile-configuration/components/funding-sources.tsx (1)

108-110: Note: Store integration appears incomplete.

Similar to the contract modal, the delete handler has commented-out dispatch logic, suggesting ongoing refactoring of store integration across profile configuration components.

🧹 Nitpick comments (13)
src/common/lib/object.ts (1)

50-54: Consider improving the type annotation.

The function logic is correct, but the parameter type could be more precise:

-export const nullifyEmptyStrings = mapValues((value: string | unknown) => {
+export const nullifyEmptyStrings = mapValues((value: unknown) => {

Since the function handles any type of value and only processes strings, unknown is more appropriate than string | unknown.

src/features/profile-configuration/types.ts (1)

1-1: Type alias is concise and self-explanatory.

Consider adding JSDoc explaining when each mode is used, but otherwise this is fine.

src/entities/list/components/AccountCard.tsx (1)

145-145: Verify empty-description layout in AccountCard

The <p> wrapper in src/entities/list/components/AccountCard.tsx always renders (with className="mt-2 h-14 overflow-hidden …"), so hiding the description leaves a blank 3.5 rem–tall space instead of “N/A”. Please confirm that this behavior is intended and that the empty area doesn’t break the card layout or confuse users.

• File: src/entities/list/components/AccountCard.tsx
Line 145 – <p className="mt-2 h-14 …">…</p> now renders empty when profile.description is undefined.
• Compare with:
PotSponsorsBoard.tsx (uses empty-string fallback)
AccountSummaryPopup.tsx (falls back to “No description provided”)

Check both visual spacing and screen-reader accessibility for cards with no description.

src/entities/_shared/account/utils/linktree.ts (1)

7-13: LGTM! Well-structured higher-order function with proper edge case handling.

The implementation correctly handles various URL scenarios and follows a clean functional pattern. The logic flow is sound: validate input → test regex → extract or return original.

Consider adding a more specific return type for better type safety:

-export const getLinktreeLeafExtractor = (key: AccountProfileLinktreeKey) => (url?: string) => {
+export const getLinktreeLeafExtractor = (key: AccountProfileLinktreeKey) => (url?: string): string | undefined => {
src/common/contracts/tokens/non-fungible/hooks.ts (1)

9-24: Consider renaming for clarity.

The implementation follows established patterns and correctly handles conditional activation, client-side execution, and error cases. However, consider renaming this hook to useNonFungibleToken or useNftToken to distinguish it from the fungible token useToken hook that was renamed to useFungibleToken elsewhere in the codebase.

-export const useToken = ({
+export const useNonFungibleToken = ({

This would maintain consistency with the fungible token naming convention and prevent confusion.

src/features/profile-configuration/components/linktree-section.tsx (1)

1-92: Well-structured form component with good UX design.

The component properly integrates with react-hook-form and provides excellent UX with prefixed input extensions showing the URL structure. The use of FieldInputExtension for consistent styling is a good design pattern.

However, address the unnecessary fragments flagged by static analysis:

- labelExtension={<></>}
+ labelExtension=""

Apply this change to all four FormField instances (lines 34, 50, 66, 82).

src/features/profile-configuration/utils/normalization.ts (1)

35-41: Consider consistent handling of empty arrays in JSON serialization.

The serialization logic is mostly consistent, but there's an inconsistency in how empty arrays are handled:

  • plCategories: Always serialized (line 35)
  • plTeam: Only serialized if length > 0 (line 40)
  • Other arrays: Only serialized if truthy (lines 36-39)

Consider standardizing the empty array handling approach:

- plCategories: JSON.stringify(inputs.categories),
+ plCategories: inputs.categories.length > 0 ? JSON.stringify(inputs.categories) : undefined,

Or alternatively, ensure categories are always required to have at least one item in the schema validation.

src/features/profile-configuration/components/repositories-section.tsx (1)

8-19: Review local extractFromUrl implementation for edge cases.

The local implementation looks functionally correct, but consider a few potential improvements:

  1. The leading slash removal logic could be more explicit
  2. The fallback to the original URL when no match is found is good
  3. Consider handling empty string input
 const extractFromUrl = (url: string, pattern: RegExp) => {
-  if (url) {
+  if (url && url.trim().length > 0) {
     if (url.startsWith("/")) {
       url = url.slice(1, url.length);
     }
 
     // Execute the regular expression on the URL
     const match = url.match(pattern);
     // If a match is found, return the extracted repository path; otherwise, return the original URL
     return match ? match[1] : url;
   }
+  return "";
 };
src/common/ui/form/components/richtext.tsx (2)

151-162: Consider improving the UX for link insertion

Using window.prompt for URL input provides a poor user experience. Consider implementing a custom modal or popover for link insertion that includes URL validation feedback.

Example implementation approach:

-const addLink = useCallback(() => {
-  // Don't allow adding links if we're at the limit
-  if (isAtLimit) {
-    return;
-  }
-
-  const url = window.prompt("Enter URL:");
-
-  if (url && editor) {
-    editor.chain().focus().setLink({ href: url }).run();
-  }
-}, [editor, isAtLimit]);
+const addLink = useCallback(() => {
+  // Don't allow adding links if we're at the limit
+  if (isAtLimit) {
+    return;
+  }
+
+  // Consider using a custom modal or popover component
+  // that provides better UX with URL validation
+  // Example: openLinkModal({ onConfirm: (url) => { ... } })
+  const url = window.prompt("Enter URL:");
+
+  if (url && editor) {
+    // Add URL validation before setting the link
+    if (isValidHttpUrl(url)) {
+      editor.chain().focus().setLink({ href: url }).run();
+    } else {
+      // Show validation error
+    }
+  }
+}, [editor, isAtLimit]);

61-69: Character count calculation could be optimized

The wouldExceedLimit function creates a DOM element on every call. Consider memoizing this or using a more efficient approach.

-const wouldExceedLimit = useCallback(
-  (newContent: string) => {
-    const tempDiv = document.createElement("div");
-    tempDiv.innerHTML = newContent;
-    const textLength = tempDiv.textContent?.length || 0;
-    return textLength > maxLength;
-  },
-  [maxLength],
-);
+const getTextLength = useCallback((html: string) => {
+  const tempDiv = document.createElement("div");
+  tempDiv.innerHTML = html;
+  return tempDiv.textContent?.length || 0;
+}, []);
+
+const wouldExceedLimit = useCallback(
+  (newContent: string) => getTextLength(newContent) > maxLength,
+  [getTextLength, maxLength],
+);
src/features/profile-configuration/components/editor.tsx (2)

213-257: Clarify the status of commented sections

Large sections for smart contracts, funding sources, and repositories are commented out. This needs clarification:

  • Are these features being deprecated?
  • Are they temporarily disabled for this release?
  • Should these be removed entirely rather than left as comments?

Would you like me to help determine whether these sections should be removed or create a tracking issue for re-enabling them?


266-266: Verify router.back() behavior

Using router.back() for cancel might not always return to the expected page if the user navigated directly to this form. Consider using a specific route instead.

-<Button variant="standard-outline" onClick={router.back}>
+<Button variant="standard-outline" onClick={() => router.push(rootPathnames.PROFILE(accountId))}>
src/features/profile-configuration/models/deprecated.ts (1)

42-101: Inconsistent state mutation patterns in reducers.

The reducers show inconsistent approaches to state management:

  • Some directly mutate state (e.g., setDaoProjectProposal, setIsDao)
  • Others create new arrays but still mutate state properties (e.g., updateFundingSource)
  • Some use proper immutable patterns (e.g., removeSmartContract, updateRepositories)

While this is deprecated code, the inconsistency suggests the original implementation may not have followed a consistent state management pattern.

For reference purposes, here's how the direct mutations could be made consistent:

-    setDaoProjectProposal(state: ProjectEditorState, daoProjectProposal: Proposal | null) {
-      state.daoProjectProposal = daoProjectProposal;
-    },
+    setDaoProjectProposal(state: ProjectEditorState, daoProjectProposal: Proposal | null) {
+      return { ...state, daoProjectProposal };
+    },
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 12a0ef6 and 54a2b0f.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (107)
  • .vscode/settings.json (1 hunks)
  • package.json (3 hunks)
  • src/common/_config/production.env-config.ts (2 hunks)
  • src/common/_config/staging.env-config.ts (2 hunks)
  • src/common/_config/test.env-config.ts (1 hunks)
  • src/common/api/coingecko/hooks.ts (2 hunks)
  • src/common/api/indexer/hooks.ts (1 hunks)
  • src/common/api/intear-token-indexer/hooks.ts (1 hunks)
  • src/common/api/near-social-indexer/hooks.ts (1 hunks)
  • src/common/blockchains/near-protocol/hooks.ts (3 hunks)
  • src/common/constants.ts (5 hunks)
  • src/common/contracts/social-db/hooks.ts (1 hunks)
  • src/common/contracts/tokens/fungible/client.ts (1 hunks)
  • src/common/contracts/tokens/fungible/hooks.ts (1 hunks)
  • src/common/contracts/tokens/index.ts (1 hunks)
  • src/common/contracts/tokens/non-fungible/client.ts (1 hunks)
  • src/common/contracts/tokens/non-fungible/hooks.ts (1 hunks)
  • src/common/contracts/tokens/non-fungible/index.ts (1 hunks)
  • src/common/contracts/tokens/non-fungible/interfaces.ts (1 hunks)
  • src/common/lib/object.ts (2 hunks)
  • src/common/lib/string.ts (1 hunks)
  • src/common/services/images.ts (0 hunks)
  • src/common/services/pinata/hooks.ts (1 hunks)
  • src/common/types.ts (3 hunks)
  • src/common/ui/form/components/index.ts (1 hunks)
  • src/common/ui/form/components/richtext.tsx (1 hunks)
  • src/common/ui/form/components/text.tsx (3 hunks)
  • src/common/ui/layout/components/molecules/multi-select.tsx (5 hunks)
  • src/common/ui/layout/svg/CameraIcon.tsx (0 hunks)
  • src/common/ui/layout/svg/camera.tsx (0 hunks)
  • src/entities/_shared/account/components/AccountFollowButton.tsx (2 hunks)
  • src/entities/_shared/account/components/AccountFollowStats.tsx (2 hunks)
  • src/entities/_shared/account/components/profile-images.tsx (2 hunks)
  • src/entities/_shared/account/constants.ts (2 hunks)
  • src/entities/_shared/account/hooks/social-image.ts (1 hunks)
  • src/entities/_shared/account/hooks/social-profile.ts (1 hunks)
  • src/entities/_shared/account/index.ts (1 hunks)
  • src/entities/_shared/account/types.ts (1 hunks)
  • src/entities/_shared/account/utils/linktree.ts (1 hunks)
  • src/entities/_shared/index.ts (0 hunks)
  • src/entities/_shared/token/components/balance.tsx (2 hunks)
  • src/entities/_shared/token/components/icons.tsx (2 hunks)
  • src/entities/_shared/token/components/selector.tsx (3 hunks)
  • src/entities/_shared/token/components/value-summary.tsx (2 hunks)
  • src/entities/_shared/token/hooks/_deprecated.ts (1 hunks)
  • src/entities/_shared/token/hooks/fungible.ts (6 hunks)
  • src/entities/_shared/token/index.ts (1 hunks)
  • src/entities/campaign/components/CampaignBanner.tsx (5 hunks)
  • src/entities/campaign/components/CampaignCard.tsx (2 hunks)
  • src/entities/campaign/components/CampaignCarouselItem.tsx (2 hunks)
  • src/entities/campaign/components/CampaignDonorsTable.tsx (1 hunks)
  • src/entities/campaign/components/CampaignProgressBar.tsx (2 hunks)
  • src/entities/campaign/components/CampaignSettings.tsx (4 hunks)
  • src/entities/campaign/components/editor.tsx (5 hunks)
  • src/entities/campaign/hooks/forms.ts (2 hunks)
  • src/entities/campaign/models/schema.ts (1 hunks)
  • src/entities/list/components/AccountCard.tsx (2 hunks)
  • src/entities/list/components/ListAccounts.tsx (1 hunks)
  • src/entities/list/components/ListCard.tsx (2 hunks)
  • src/entities/list/components/ListDetails.tsx (2 hunks)
  • src/entities/list/hooks/registrations.ts (1 hunks)
  • src/entities/post/components/PostEditor.tsx (2 hunks)
  • src/entities/pot/components/PotCard.tsx (2 hunks)
  • src/entities/pot/components/PotDonationEntry.tsx (2 hunks)
  • src/entities/pot/components/PotDonationStats.tsx (3 hunks)
  • src/entities/voting-round/components/WinnerRow.tsx (2 hunks)
  • src/entities/voting-round/hooks/results.ts (2 hunks)
  • src/entities/voting-round/hooks/voter-profile.ts (2 hunks)
  • src/entities/voting-round/model/types.ts (1 hunks)
  • src/features/donation/components/campaign-success-share.tsx (1 hunks)
  • src/features/donation/components/group-allocation-recipients.tsx (2 hunks)
  • src/features/donation/components/group-allocation-success.tsx (2 hunks)
  • src/features/donation/components/group-allocation.tsx (3 hunks)
  • src/features/donation/components/modal-content.tsx (3 hunks)
  • src/features/donation/components/single-recipient-allocation.tsx (8 hunks)
  • src/features/donation/components/single-recipient-success-share.tsx (1 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 (2 hunks)
  • src/features/donation/models/effects/campaign-ft-donation.ts (10 hunks)
  • src/features/donation/models/effects/direct-ft-donation.ts (8 hunks)
  • src/features/pot-application/hooks/clearance.ts (2 hunks)
  • src/features/profile-configuration/components/AddFundingSourceModal.tsx (3 hunks)
  • src/features/profile-configuration/components/contract-modal.tsx (1 hunks)
  • src/features/profile-configuration/components/contracts-section.tsx (3 hunks)
  • src/features/profile-configuration/components/dao-progress.tsx (1 hunks)
  • src/features/profile-configuration/components/editor-elements.tsx (4 hunks)
  • src/features/profile-configuration/components/editor.tsx (10 hunks)
  • src/features/profile-configuration/components/funding-sources.tsx (2 hunks)
  • src/features/profile-configuration/components/image-upload.tsx (1 hunks)
  • src/features/profile-configuration/components/linktree-section.tsx (1 hunks)
  • src/features/profile-configuration/components/repositories-section.tsx (2 hunks)
  • src/features/profile-configuration/hooks/forms.ts (2 hunks)
  • src/features/profile-configuration/index.ts (1 hunks)
  • src/features/profile-configuration/models/deprecated.ts (1 hunks)
  • src/features/profile-configuration/models/effects.ts (3 hunks)
  • src/features/profile-configuration/models/schemas.ts (2 hunks)
  • src/features/profile-configuration/models/types.ts (1 hunks)
  • src/features/profile-configuration/types.ts (1 hunks)
  • src/features/profile-configuration/utils/normalization.ts (1 hunks)
  • src/features/profile-setup/components/image-upload.tsx (0 hunks)
  • src/features/profile-setup/components/linktree-section.tsx (0 hunks)
  • src/features/profile-setup/index.ts (0 hunks)
  • src/features/profile-setup/models/deprecated.ts (0 hunks)
  • src/features/profile-setup/models/types.ts (0 hunks)
  • src/features/profile-setup/types.ts (0 hunks)
  • src/features/profile-setup/utils/normalization.ts (0 hunks)
⛔ Files not processed due to max files limit (14)
  • src/features/proportional-funding/components/payout-manager.tsx
  • src/layout/components/user-dropdown.tsx
  • src/layout/profile/_deprecated/DonationItem.tsx
  • src/layout/profile/components/header.tsx
  • src/layout/profile/components/hero.tsx
  • src/layout/profile/components/layout.tsx
  • src/layout/profile/components/summary.tsx
  • src/layout/profile/components/team.tsx
  • src/pages/index.tsx
  • src/pages/pot/[potId]/applications.tsx
  • src/pages/pot/[potId]/payouts.tsx
  • src/pages/profile/[accountId]/edit.tsx
  • src/pages/profile/[accountId]/home.tsx
  • src/pages/register.tsx
💤 Files with no reviewable changes (11)
  • src/entities/_shared/index.ts
  • src/features/profile-setup/index.ts
  • src/features/profile-setup/types.ts
  • src/common/ui/layout/svg/camera.tsx
  • src/common/ui/layout/svg/CameraIcon.tsx
  • src/features/profile-setup/components/image-upload.tsx
  • src/features/profile-setup/components/linktree-section.tsx
  • src/common/services/images.ts
  • src/features/profile-setup/utils/normalization.ts
  • src/features/profile-setup/models/types.ts
  • src/features/profile-setup/models/deprecated.ts
🧰 Additional context used
🧠 Learnings (77)
src/entities/list/hooks/registrations.ts (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/features/donation/components/single-recipient-success-share.tsx (5)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
src/entities/voting-round/model/types.ts (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.
src/entities/_shared/token/hooks/_deprecated.ts (4)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/features/donation/components/campaign-success-share.tsx (5)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
src/common/lib/object.ts (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/entities/campaign/components/CampaignForm.tsx:90-115
Timestamp: 2025-05-24T01:24:21.592Z
Learning: The parseNumber and parseBig utility functions in src/common/lib/numeric.ts are robust and handle all edge cases including empty strings, null/undefined values, invalid strings, and locale-specific decimal formatting. They always return valid results, making additional null checks before using them unnecessary.
src/common/ui/form/components/index.ts (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
src/features/donation/components/group-allocation-success.tsx (11)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
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.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/common/_config/test.env-config.ts (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
src/features/pot-application/hooks/clearance.ts (6)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
src/entities/pot/components/PotDonationEntry.tsx (3)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
src/entities/list/components/ListCard.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/entities/_shared/account/components/AccountFollowButton.tsx (4)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
src/entities/campaign/components/CampaignDonorsTable.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
src/entities/campaign/models/schema.ts (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/models/effects/ft.ts:37-41
Timestamp: 2025-04-27T20:37:55.330Z
Learning: In the donation flow, message length is already restricted through schema validation with `message: string().max(DONATION_MAX_MESSAGE_LENGTH)` where `DONATION_MAX_MESSAGE_LENGTH = 100`. This validation prevents unbounded messages that could lead to disproportionate storage deposits in the `donationFtMulticall` function.
src/entities/voting-round/components/WinnerRow.tsx (1)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
src/entities/voting-round/hooks/voter-profile.ts (3)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/entities/_shared/token/components/value-summary.tsx (4)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is used via the useToast() hook which returns a toast() function. The toast() function accepts an object with title, description, and variant properties, rather than having separate success/error methods.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
src/entities/_shared/token/components/icons.tsx (5)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is used via the useToast() hook which returns a toast() function. The toast() function accepts an object with title, description, and variant properties, rather than having separate success/error methods.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/features/donation/hooks/form.ts (12)
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.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:43:02.493Z
Learning: For error handling in the UI, use the `useToast` hook from the UI kit instead of Redux dispatch, as the codebase aims to minimize Redux usage.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is used via the useToast() hook which returns a toast() function. The toast() function accepts an object with title, description, and variant properties, rather than having separate success/error methods.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation.tsx:50-56
Timestamp: 2025-05-13T04:00:23.459Z
Learning: In react-hook-form, `form.watch()` method does trigger component re-renders when the watched field values change, similar to `useWatch()`. The main difference is that `useWatch()` is more granular and only re-renders the component it's used in, while `form.watch()` may cause the parent component to re-render.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/entities/_shared/token/components/balance.tsx (3)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
src/entities/list/components/ListDetails.tsx (2)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:43:02.493Z
Learning: For error handling in the UI, use the `useToast` hook from the UI kit instead of Redux dispatch, as the codebase aims to minimize Redux usage.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
src/entities/campaign/components/CampaignSettings.tsx (8)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides comprehensive error handling including loading state management, success/error callbacks, error logging, and proper cleanup.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which manages loading state and provides success/error callbacks for UI feedback.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
src/entities/campaign/components/CampaignCarouselItem.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
src/entities/_shared/account/index.ts (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
src/entities/voting-round/hooks/results.ts (8)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/features/donation/models/effects/campaign-ft-donation.ts (6)
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.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/models/effects/ft.ts:37-41
Timestamp: 2025-04-27T20:37:55.330Z
Learning: In the donation flow, message length is already restricted through schema validation with `message: string().max(DONATION_MAX_MESSAGE_LENGTH)` where `DONATION_MAX_MESSAGE_LENGTH = 100`. This validation prevents unbounded messages that could lead to disproportionate storage deposits in the `donationFtMulticall` function.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
src/common/api/indexer/hooks.ts (3)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/common/ui/form/components/text.tsx (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
src/entities/pot/components/PotCard.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/features/donation/components/group-allocation-recipients.tsx (8)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation-recipients.tsx:51-58
Timestamp: 2025-05-13T03:43:51.352Z
Learning: In the donation feature of PotLock, the group allocation recipients component handles mutually exclusive data sources - either pot applications or list registrations will be available at any given time, but never both simultaneously. This makes deduplication of combined recipient IDs unnecessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
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.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:43:02.493Z
Learning: For error handling in the UI, use the `useToast` hook from the UI kit instead of Redux dispatch, as the codebase aims to minimize Redux usage.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/entities/_shared/account/utils/linktree.ts (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
src/common/_config/staging.env-config.ts (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
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.
src/entities/list/components/AccountCard.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/common/contracts/tokens/fungible/client.ts (4)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
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.
src/features/donation/components/single-recipient-success.tsx (5)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
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.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/entities/campaign/components/CampaignProgressBar.tsx (4)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
src/entities/pot/components/PotDonationStats.tsx (7)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
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.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:43:02.493Z
Learning: For error handling in the UI, use the `useToast` hook from the UI kit instead of Redux dispatch, as the codebase aims to minimize Redux usage.
src/entities/_shared/account/components/AccountFollowStats.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/features/donation/components/modal-content.tsx (5)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
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.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:43:02.493Z
Learning: For error handling in the UI, use the `useToast` hook from the UI kit instead of Redux dispatch, as the codebase aims to minimize Redux usage.
src/features/donation/models/effects/direct-ft-donation.ts (5)
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.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/models/effects/ft.ts:37-41
Timestamp: 2025-04-27T20:37:55.330Z
Learning: In the donation flow, message length is already restricted through schema validation with `message: string().max(DONATION_MAX_MESSAGE_LENGTH)` where `DONATION_MAX_MESSAGE_LENGTH = 100`. This validation prevents unbounded messages that could lead to disproportionate storage deposits in the `donationFtMulticall` function.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
src/entities/campaign/hooks/forms.ts (11)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation.tsx:50-56
Timestamp: 2025-05-13T04:00:23.459Z
Learning: In react-hook-form, `form.watch()` method does trigger component re-renders when the watched field values change, similar to `useWatch()`. The main difference is that `useWatch()` is more granular and only re-renders the component it's used in, while `form.watch()` may cause the parent component to re-render.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:43:02.493Z
Learning: For error handling in the UI, use the `useToast` hook from the UI kit instead of Redux dispatch, as the codebase aims to minimize Redux usage.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is used via the useToast() hook which returns a toast() function. The toast() function accepts an object with title, description, and variant properties, rather than having separate success/error methods.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
src/entities/_shared/token/components/selector.tsx (6)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
src/features/donation/components/group-allocation.tsx (6)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
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.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
src/entities/post/components/PostEditor.tsx (4)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
src/common/types.ts (6)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
src/common/_config/production.env-config.ts (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
src/features/donation/components/user-entrypoints.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
src/entities/campaign/components/CampaignCard.tsx (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
src/entities/_shared/account/hooks/social-profile.ts (5)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/common/api/coingecko/hooks.ts (1)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/entities/campaign/components/CampaignBanner.tsx (13)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides comprehensive error handling including loading state management, success/error callbacks, error logging, and proper cleanup.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which manages loading state and provides success/error callbacks for UI feedback.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides `onPublishSuccess` and `onPublishError` callbacks for proper error handling in the UI layer.
src/features/profile-configuration/components/editor-elements.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation.tsx:50-56
Timestamp: 2025-05-13T04:00:23.459Z
Learning: In react-hook-form, `form.watch()` method does trigger component re-renders when the watched field values change, similar to `useWatch()`. The main difference is that `useWatch()` is more granular and only re-renders the component it's used in, while `form.watch()` may cause the parent component to re-render.
src/common/contracts/social-db/hooks.ts (3)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/entities/_shared/account/hooks/social-image.ts (3)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/features/profile-configuration/models/effects.ts (3)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/common/api/near-social-indexer/hooks.ts (3)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/features/profile-configuration/models/schemas.ts (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
src/common/contracts/tokens/non-fungible/client.ts (3)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/common/api/intear-token-indexer/hooks.ts (1)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/entities/_shared/account/components/profile-images.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/common/contracts/tokens/non-fungible/hooks.ts (5)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
src/features/profile-configuration/utils/normalization.ts (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
src/features/profile-configuration/components/linktree-section.tsx (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
src/entities/campaign/components/editor.tsx (5)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/entities/campaign/components/CampaignForm.tsx:90-115
Timestamp: 2025-05-24T01:24:21.592Z
Learning: The parseNumber and parseBig utility functions in src/common/lib/numeric.ts are robust and handle all edge cases including empty strings, null/undefined values, invalid strings, and locale-specific decimal formatting. They always return valid results, making additional null checks before using them unnecessary.
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.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/common/contracts/tokens/non-fungible/interfaces.ts (2)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
src/common/contracts/tokens/fungible/hooks.ts (4)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
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.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/features/profile-configuration/components/AddFundingSourceModal.tsx (4)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:43:02.493Z
Learning: For error handling in the UI, use the `useToast` hook from the UI kit instead of Redux dispatch, as the codebase aims to minimize Redux usage.
src/common/contracts/tokens/non-fungible/index.ts (1)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
src/entities/_shared/token/hooks/fungible.ts (6)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
src/common/ui/form/components/richtext.tsx (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
src/common/blockchains/near-protocol/hooks.ts (3)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
src/features/profile-configuration/components/image-upload.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/features/profile-configuration/hooks/forms.ts (3)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation.tsx:50-56
Timestamp: 2025-05-13T04:00:23.459Z
Learning: In react-hook-form, `form.watch()` method does trigger component re-renders when the watched field values change, similar to `useWatch()`. The main difference is that `useWatch()` is more granular and only re-renders the component it's used in, while `form.watch()` may cause the parent component to re-render.
src/features/donation/components/single-recipient-allocation.tsx (11)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation-recipients.tsx:51-58
Timestamp: 2025-05-13T03:43:51.352Z
Learning: In the donation feature of PotLock, the group allocation recipients component handles mutually exclusive data sources - either pot applications or list registrations will be available at any given time, but never both simultaneously. This makes deduplication of combined recipient IDs unnecessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.
src/features/profile-configuration/components/editor.tsx (4)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
src/entities/_shared/account/constants.ts (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
🧬 Code Graph Analysis (53)
src/features/donation/components/group-allocation-success.tsx (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/features/pot-application/hooks/clearance.ts (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/entities/list/components/ListCard.tsx (2)
src/common/lib/string.ts (1)
  • truncate (1-7)
src/common/contracts/core/lists/index.ts (1)
  • listsContractClient (7-7)
src/entities/campaign/components/CampaignDonorsTable.tsx (3)
src/common/types.ts (1)
  • ByCampaignId (131-133)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (118-118)
src/entities/voting-round/components/WinnerRow.tsx (2)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (118-118)
src/entities/voting-round/hooks/voter-profile.ts (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/common/services/pinata/hooks.ts (1)
src/common/services/pinata/client.ts (1)
  • upload (17-20)
src/entities/_shared/token/components/icons.tsx (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/features/donation/hooks/form.ts (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/entities/_shared/token/components/balance.tsx (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/entities/list/components/ListDetails.tsx (1)
src/common/lib/string.ts (1)
  • truncate (1-7)
src/entities/campaign/components/CampaignSettings.tsx (2)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (118-118)
src/entities/voting-round/hooks/results.ts (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/features/profile-configuration/models/types.ts (1)
src/features/profile-configuration/models/schemas.ts (2)
  • profileConfigurationSchema (31-61)
  • addFundingSourceSchema (5-27)
src/entities/pot/components/PotCard.tsx (2)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (118-118)
src/features/donation/components/group-allocation-recipients.tsx (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/entities/_shared/account/utils/linktree.ts (2)
src/entities/_shared/account/types.ts (1)
  • AccountProfileLinktreeKey (21-21)
src/entities/_shared/account/constants.ts (1)
  • ACCOUNT_PROFILE_URL_PATTERNS (29-34)
src/entities/list/components/AccountCard.tsx (1)
src/common/lib/string.ts (1)
  • truncate (1-7)
src/common/contracts/tokens/fungible/client.ts (3)
src/common/types.ts (2)
  • ByTokenId (116-121)
  • ByAccountId (47-49)
src/common/blockchains/near-protocol/index.ts (1)
  • nearProtocolClient (6-6)
src/common/contracts/tokens/fungible/interfaces.ts (1)
  • FungibleTokenMetadata (1-9)
src/entities/campaign/components/CampaignProgressBar.tsx (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/entities/pot/components/PotDonationStats.tsx (2)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (118-118)
src/features/donation/components/modal-content.tsx (1)
src/common/contracts/core/donation/index.ts (1)
  • donationContractHooks (7-7)
src/entities/campaign/hooks/forms.ts (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/entities/_shared/token/components/selector.tsx (1)
src/entities/_shared/token/hooks/fungible.ts (2)
  • useFungibleToken (35-197)
  • useFungibleTokenAllowlist (16-28)
src/features/donation/components/group-allocation.tsx (1)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/entities/post/components/PostEditor.tsx (1)
src/entities/_shared/account/hooks/social-profile.ts (1)
  • useAccountSocialProfile (12-46)
src/common/types.ts (1)
src/common/contracts/core/voting/interfaces.ts (1)
  • AccountId (1-1)
src/features/donation/components/user-entrypoints.tsx (2)
src/common/types.ts (1)
  • ByAccountId (47-49)
src/features/donation/hooks/user-flow.ts (1)
  • useDonationUserFlow (15-44)
src/entities/_shared/account/hooks/social-profile.ts (3)
src/common/types.ts (3)
  • ByAccountId (47-49)
  • ConditionalActivation (95-97)
  • LiveUpdateParams (99-101)
src/entities/_shared/account/hooks/social-image.ts (1)
  • useAccountSocialImageSrc (15-53)
src/entities/_shared/account/constants.ts (2)
  • ACCOUNT_PROFILE_IMAGE_PLACEHOLDER_SRC (14-15)
  • ACCOUNT_PROFILE_COVER_IMAGE_PLACEHOLDER_SRC (19-20)
src/common/api/coingecko/hooks.ts (2)
src/common/types.ts (1)
  • ConditionalActivation (95-97)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (118-118)
src/entities/campaign/components/CampaignBanner.tsx (4)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (118-118)
src/entities/_shared/account/components/AccountProfileLink.tsx (1)
  • AccountProfileLink (19-47)
src/common/ui/layout/svg/BadgeIcon.tsx (1)
  • BadgeIcon (1-15)
src/features/profile-configuration/components/funding-sources.tsx (1)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/common/contracts/social-db/hooks.ts (2)
src/common/types.ts (3)
  • ByAccountId (47-49)
  • ConditionalActivation (95-97)
  • LiveUpdateParams (99-101)
src/common/constants.ts (1)
  • IS_CLIENT (13-13)
src/entities/_shared/account/hooks/social-image.ts (3)
src/common/contracts/tokens/non-fungible/index.ts (1)
  • nftContractHooks (7-7)
src/common/constants.ts (1)
  • NOOP_STRING (164-164)
src/common/lib/string.ts (1)
  • isValidHttpUrl (27-33)
src/features/profile-configuration/models/effects.ts (4)
src/common/types.ts (1)
  • ByAccountId (47-49)
src/features/profile-configuration/types.ts (1)
  • ProfileConfigurationMode (1-1)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/features/profile-configuration/utils/normalization.ts (1)
  • profileConfigurationInputsToSocialDbFormat (15-41)
src/common/api/near-social-indexer/hooks.ts (1)
src/common/types.ts (2)
  • ByAccountId (47-49)
  • ConditionalActivation (95-97)
src/features/profile-configuration/models/schemas.ts (1)
src/entities/_shared/account/constants.ts (1)
  • ACCOUNT_PROFILE_DESCRIPTION_MAX_LENGTH (10-10)
src/common/contracts/tokens/non-fungible/client.ts (3)
src/common/contracts/tokens/non-fungible/interfaces.ts (3)
  • NonFungibleTokenLookupParams (116-119)
  • NonFungibleToken (110-114)
  • NonFungibleTokenContractMetadata (71-108)
src/common/blockchains/near-protocol/index.ts (1)
  • nearProtocolClient (6-6)
src/common/types.ts (1)
  • ByContractAccountId (51-53)
src/common/api/intear-token-indexer/hooks.ts (1)
src/common/types.ts (3)
  • ByTokenId (116-121)
  • ConditionalActivation (95-97)
  • LiveUpdateParams (99-101)
src/entities/_shared/account/components/profile-images.tsx (2)
src/entities/_shared/account/hooks/social-profile.ts (1)
  • useAccountSocialProfile (12-46)
src/entities/_shared/account/constants.ts (1)
  • ACCOUNT_PROFILE_COVER_IMAGE_PLACEHOLDER_SRC (19-20)
src/common/contracts/tokens/non-fungible/hooks.ts (3)
src/common/contracts/tokens/non-fungible/interfaces.ts (1)
  • NonFungibleTokenLookupParams (116-119)
src/common/types.ts (1)
  • ConditionalActivation (95-97)
src/common/constants.ts (2)
  • IS_CLIENT (13-13)
  • CONTRACT_SWR_CONFIG (168-172)
src/features/profile-configuration/components/contract-modal.tsx (1)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/features/profile-configuration/utils/normalization.ts (3)
src/entities/_shared/account/utils/linktree.ts (1)
  • getLinktreeLeafExtractor (7-13)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/common/lib/object.ts (1)
  • nullifyEmptyStrings (50-54)
src/features/profile-configuration/components/linktree-section.tsx (2)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/common/ui/form/components/text.tsx (1)
  • TextField (30-163)
src/features/profile-configuration/components/repositories-section.tsx (1)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/features/profile-configuration/components/contracts-section.tsx (1)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/common/contracts/tokens/fungible/hooks.ts (2)
src/common/types.ts (4)
  • ByTokenId (116-121)
  • ConditionalActivation (95-97)
  • LiveUpdateParams (99-101)
  • ByAccountId (47-49)
src/common/constants.ts (1)
  • IS_CLIENT (13-13)
src/features/profile-configuration/components/AddFundingSourceModal.tsx (2)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/common/ui/form/components/textarea.tsx (1)
  • TextAreaField (20-66)
src/entities/_shared/token/hooks/fungible.ts (4)
src/common/types.ts (2)
  • ConditionalActivation (95-97)
  • LiveUpdateParams (99-101)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (118-118)
src/common/api/coingecko/index.ts (1)
  • coingeckoHooks (5-5)
src/common/blockchains/near-protocol/index.ts (1)
  • nearProtocolHooks (6-6)
src/common/blockchains/near-protocol/hooks.ts (2)
src/common/types.ts (3)
  • ConditionalActivation (95-97)
  • ByAccountId (47-49)
  • LiveUpdateParams (99-101)
src/common/constants.ts (2)
  • NATIVE_TOKEN_ID (118-118)
  • IS_CLIENT (13-13)
src/features/profile-configuration/components/image-upload.tsx (3)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/common/services/pinata/client.ts (1)
  • FileUploadResult (22-25)
src/common/services/pinata/index.ts (1)
  • pinataHooks (7-7)
src/features/profile-configuration/hooks/forms.ts (7)
src/common/types.ts (1)
  • ByAccountId (47-49)
src/features/profile-configuration/models/effects.ts (1)
  • ProfileSaveInputs (22-27)
src/entities/_shared/account/hooks/social-profile.ts (1)
  • useAccountSocialProfile (12-46)
src/features/profile-configuration/models/types.ts (1)
  • ProfileConfigurationInputs (5-5)
src/features/profile-configuration/utils/normalization.ts (1)
  • stripLinktree (8-13)
src/common/ui/form/hooks/enhanced.ts (1)
  • useEnhancedForm (86-124)
src/features/profile-configuration/models/schemas.ts (1)
  • profileConfigurationSchema (31-61)
src/features/profile-configuration/models/deprecated.ts (2)
src/common/types.ts (1)
  • ByAccountId (47-49)
src/features/profile-configuration/models/types.ts (2)
  • ProfileConfigurationInputs (5-5)
  • AddFundingSourceInputs (7-7)
🪛 Biome (1.9.4)
src/entities/campaign/components/CampaignSettings.tsx

[error] 166-166: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/entities/campaign/components/CampaignCarouselItem.tsx

[error] 84-84: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/common/contracts/tokens/fungible/client.ts

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

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

(lint/complexity/noBannedTypes)

src/entities/campaign/components/CampaignCard.tsx

[error] 73-73: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/entities/campaign/components/CampaignBanner.tsx

[error] 147-147: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/common/contracts/tokens/non-fungible/client.ts

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

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

(lint/complexity/noBannedTypes)

src/features/profile-configuration/components/linktree-section.tsx

[error] 34-34: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.

(lint/complexity/noUselessFragments)


[error] 50-50: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.

(lint/complexity/noUselessFragments)


[error] 66-66: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.

(lint/complexity/noUselessFragments)


[error] 82-82: Avoid using unnecessary Fragment.

A fragment is redundant if it contains only one child, or if it is the child of a html element, and is not a keyed fragment.

(lint/complexity/noUselessFragments)

🔇 Additional comments (178)
src/entities/_shared/account/types.ts (1)

48-48: LGTM - Improved comment formatting.

The change from *? to ** follows standard JSDoc comment conventions.

src/entities/voting-round/model/types.ts (1)

2-2: LGTM - Improved import organization.

The import path change from "@/entities/_shared" to "@/entities/_shared/token" aligns with the modularization effort to separate token-related functionality.

src/entities/list/components/ListAccounts.tsx (1)

6-6: LGTM - Improved import organization.

The import path change from "@/entities/_shared" to "@/entities/_shared/account" aligns with the modularization effort to separate account-related functionality.

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

16-16: LGTM - Improved import organization.

The import path change from "@/entities/_shared" to "@/entities/_shared/account" aligns with the modularization effort to separate account-related functionality.

.vscode/settings.json (1)

84-85: LGTM! Project-specific terminology added to spell checker.

Adding "Metaverse" and "Mochi" to the spell checker dictionary prevents false positive warnings for domain-specific terms used in the codebase.

src/features/donation/components/campaign-success-share.tsx (1)

15-15: LGTM! Import path refactored for better module organization.

Moving the useAccountSocialProfile import to the more specific @/entities/_shared/account path improves module granularity and aligns with the broader codebase refactoring.

src/entities/list/hooks/registrations.ts (1)

6-9: LGTM! Consistent import path refactoring.

Moving AccountCategory and AccountListRegistrationStatusVariant imports to the account-specific module path maintains consistency with the broader codebase refactoring effort.

src/features/pot-application/hooks/clearance.ts (2)

11-11: LGTM! Hook import updated to new fungible token API.

The import change from useToken to useFungibleToken aligns with the broader codebase refactoring to standardize fungible token data fetching.


34-37: LGTM! Hook usage correctly updated to new API.

The useFungibleToken hook is properly configured with the required parameters:

  • balanceCheckAccountId for balance queries
  • tokenId for the staking token

The returned data structure is correctly accessed as stakingToken?.balanceUsd in the requirements logic.

src/features/profile-configuration/components/dao-progress.tsx (1)

5-5: LGTM! Component renamed to align with updated domain terminology.

The component name change from ProfileSetupDaoProgress to ProfileConfigurationDaoProgress maintains consistency with the broader refactoring from "ProfileSetup" to "ProfileConfiguration" terminology throughout the codebase.

src/entities/_shared/token/index.ts (1)

8-8: Barrel update looks correct.

The re-export now points at ./hooks/fungible, matching the new hook location and preventing stale imports. No further action required.

src/entities/_shared/account/index.ts (1)

24-25: Good addition—linktree utils are now publicly exposed.

This aligns the account barrel file with the new profile-configuration feature that consumes getLinktreeLeafExtractor.

src/features/profile-configuration/index.ts (1)

1-1: Makes the editor component discoverable via the feature entry point.

Straightforward export; no issues spotted.

src/common/ui/form/components/index.ts (1)

5-5: LGTM - Clean export addition

The richtext component export follows the established pattern and supports the new RichTextEditor functionality mentioned in the PR summary.

src/entities/voting-round/hooks/voter-profile.ts (2)

10-10: LGTM - Import migration to fungible token hook

The import update aligns with the codebase-wide migration to standardized fungible token hooks.


37-40: LGTM - Hook call migration maintains compatibility

The useFungibleToken hook call maintains the same parameter structure as the previous useToken call. The new hook provides enhanced functionality with backward compatibility.

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

23-23: LGTM - Import standardization to fungible token module

The import update consolidates token-related functionality under the dedicated token module.


66-66: LGTM - Hook migration with compatible parameters

The simplified hook call leverages the default values (enabled: true, live: false) of useFungibleToken, maintaining the same behavior as the previous implementation.

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

16-16: LGTM - Migration to specialized token hook

The import update moves to the dedicated fungible token module for better organization.


134-137: LGTM - Enhanced hook usage with balance checking

The migration to useFungibleToken now includes balanceCheckAccountId parameter, which enables automatic balance fetching for the logged-in user. This is particularly valuable for donation forms where balance validation is crucial.

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

12-12: LGTM - Consolidated token module imports

Both useFungibleToken and TokenIcon are now imported from the dedicated token module, improving code organization and consistency across the codebase.


34-34: LGTM - Straightforward hook migration

The useFungibleToken call maintains compatibility with the previous implementation while providing access to enhanced fungible token features.

src/entities/voting-round/hooks/results.ts (2)

11-11: LGTM! Token hook import updated correctly.

The import change from useToken to useFungibleToken aligns with the systematic refactoring across the codebase to consolidate token-related hooks.


26-33: Hook usage updated correctly.

The useFungibleToken hook is being used appropriately with the correct parameters. The hook signature matches the usage pattern and maintains the same functionality as the previous useToken hook.

src/common/contracts/tokens/index.ts (1)

2-2: LGTM! NFT module export added correctly.

The addition of the non-fungible token module export follows the existing pattern and integrates NFT functionality into the unified token contracts interface.

src/common/_config/test.env-config.ts (1)

87-91: LGTM! Cart feature flag added correctly.

The new feature flag follows the established pattern with appropriate properties and is safely disabled by default in the test environment.

src/entities/voting-round/components/WinnerRow.tsx (2)

17-17: LGTM! Token hook import updated consistently.

The import change from useToken to useFungibleToken is consistent with the systematic refactoring across the codebase.


34-34: Hook usage updated correctly for native token.

The useFungibleToken hook is being used appropriately with NATIVE_TOKEN_ID to fetch native token metadata for display in the winner row component.

src/entities/list/components/ListCard.tsx (2)

47-47: Good defensive programming for list name truncation.

Adding nullish coalescing operators (?? "") ensures the truncate function always receives a string parameter, preventing potential runtime errors when dataForList?.name is undefined or null.

Also applies to: 54-54


114-114: Consistent defensive programming for owner ID truncation.

The nullish coalescing operator ensures safe string handling for the owner ID display, maintaining consistency with the other truncation calls in this component.

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

21-21: LGTM: Consistent token hook refactor

The migration from useToken to useFungibleToken aligns with the broader codebase refactor. The new hook provides more comprehensive token handling for both native and fungible tokens while maintaining the same API.

Also applies to: 92-92

src/entities/list/components/ListDetails.tsx (1)

133-133: LGTM: Defensive programming improvement

Adding nullish coalescing with empty string fallbacks ensures truncate always receives a valid string input, preventing potential edge cases and making the code more robust.

Also applies to: 142-142

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

13-13: LGTM: Consistent token refactor and improved imports

The migration to useFungibleToken and consolidated token imports improve code organization and align with the broader codebase refactor.

Also applies to: 20-20

src/entities/list/components/AccountCard.tsx (1)

34-34: LGTM: Import path modularization

Moving account-related imports to the dedicated @/entities/_shared/account module improves code organization and aligns with the broader modularization effort.

src/common/_config/staging.env-config.ts (1)

68-68: LGTM! Feature flag configuration is appropriate for staging.

The ProfileConfiguration feature flag enablement aligns with the broader refactor, and the Cart feature flag addition (while disabled) provides infrastructure for future cart functionality testing.

Also applies to: 89-93

src/entities/_shared/token/components/balance.tsx (1)

5-5: LGTM! Token hook refactor with appropriate live updates.

The migration from useToken to useFungibleToken is consistent with the broader refactor, and the addition of live: true is appropriate for balance components that need real-time balance updates.

Also applies to: 14-18

src/entities/_shared/token/components/icons.tsx (1)

8-8: LGTM! Consistent token hook refactor.

The migration from useToken to useFungibleToken with updated import path is consistent with the broader token hook consolidation effort across the codebase.

Also applies to: 32-32

src/entities/_shared/token/components/value-summary.tsx (1)

8-8: LGTM! Consistent token hook refactor.

The migration from useToken to useFungibleToken with updated import path follows the same pattern as other token components in this refactor.

Also applies to: 22-22

src/entities/pot/components/PotDonationEntry.tsx (1)

59-59: LGTM! Profile image property standardization.

The change from avatarSrc to avatar.url aligns with the profile image standardization effort. According to the retrieved learnings, the useAccountSocialProfile hook guarantees that the avatar.url property is defined through fallback URL chains.

Also applies to: 71-71

package.json (3)

2-2: LGTM: Package rename is clear and descriptive.

The rename from "@potlock/next" to "@potlock/frontend" better reflects the nature of this package.


4-4: LGTM: Appropriate version increment.

Minor version bump is suitable for the feature additions in this release.


78-81: LGTM: Consistent Tiptap dependencies for rich text editing.

All four Tiptap packages are at the same version (^2.23.0), which ensures compatibility. These dependencies support the rich text editing features mentioned in the AI summary.

src/entities/post/components/PostEditor.tsx (2)

14-17: LGTM: Updated to use new avatar object structure.

The change from avatarSrc to avatar aligns with the useAccountSocialProfile hook refactor that now returns structured objects instead of direct string URLs.


39-40: LGTM: Improved accessibility and updated avatar property access.

Good improvements:

  • Better alt text "Your avatar" instead of empty string enhances accessibility
  • Using avatar.url correctly accesses the new object structure
src/entities/pot/components/PotDonationStats.tsx (2)

9-9: LGTM: Updated to use standardized fungible token hook.

The import change from useToken to useFungibleToken aligns with the codebase-wide standardization of token data fetching.


27-27: LGTM: Consistent hook usage updates.

Both useFungibleToken calls maintain the same parameters and functionality as the previous useToken calls, ensuring no regression while adopting the new standardized hook.

Also applies to: 81-81

src/entities/pot/components/PotCard.tsx (2)

9-9: LGTM: Import updated for token hook standardization.

Consistent with the codebase-wide migration from useToken to useFungibleToken.


24-27: LGTM: Deprecated comment and hook usage properly updated.

Good maintenance:

  • The deprecated comment correctly references useFungibleToken instead of the old useToken
  • Hook call updated consistently while maintaining the same functionality
src/entities/_shared/token/components/selector.tsx (2)

15-15: LGTM: Updated imports for fungible token hook standardization.

The change from ../hooks/data to ../hooks/fungible reflects the module reorganization, and the hook renames (useTokenuseFungibleToken, useTokenAllowlistuseFungibleTokenAllowlist) align with the codebase-wide standardization.


29-32: LGTM: Hook calls updated consistently.

Both useFungibleToken and useFungibleTokenAllowlist calls maintain the same parameter structure and functionality as their predecessors, ensuring seamless migration to the new standardized hooks.

Also applies to: 71-73

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

24-29: LGTM! Token hook migration is correctly implemented.

The import change from useToken to useFungibleToken is consistent with the broader refactor across the codebase. The new hook provides the same functionality with a more specific name for fungible tokens.


59-62: Hook usage updated correctly.

The useFungibleToken hook call maintains the same parameters as the previous useToken implementation, ensuring functional compatibility.

src/common/contracts/tokens/fungible/client.ts (3)

1-1: Good refactor to namespace imports.

Using namespace imports for nearProtocolClient improves code organization and makes the relationship between related exports clearer.


13-18: Client call updated correctly.

The update to use nearProtocolClient.naxiosInstance is consistent with the namespace import change.


7-10: Fix empty object type usage.

The static analysis tool correctly identifies an issue with using {} as a type parameter.

-    .view<{}, FungibleTokenMetadata>("ft_metadata")
+    .view<Record<string, never>, FungibleTokenMetadata>("ft_metadata")
⛔ Skipped due to learnings
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:52-54
Timestamp: 2025-04-17T13:43:20.399Z
Learning: In the PotLock codebase, the `view` method has the signature `view<A extends {}, R>(method: string, props?: ViewMethodArgs<A>, config?: BuildViewInterfaceConfig): Promise<R>` and requires using `{}` as the first type parameter when there are no arguments, even though linters may flag this as a banned type.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/hooks/allocation.ts:118-121
Timestamp: 2025-04-27T20:32:05.897Z
Learning: In the PotLock codebase, the `ByTokenId` type is the exclusive source of the `tokenId` property, and extending a type with `ByTokenId` does not cause property duplication.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
src/common/api/indexer/hooks.ts (1)

96-100: Excellent improvement to error handling.

The addition of shouldRetryOnError: (err) => err.status !== 404 prevents unnecessary retries when a resource doesn't exist, which is the appropriate behavior for 404 errors. This improves both performance and user experience.

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

8-9: Good improvements to imports.

Both changes improve code organization:

  1. More specific import path for AccountListItem from the account submodule
  2. Migration to useFungibleToken for better semantic clarity

28-31: Token hook migration implemented correctly.

The useFungibleToken hook call maintains the same parameter structure as the previous useToken implementation, ensuring backward compatibility.

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

15-15: Token hook import migration completed.

The import change to useFungibleToken from the more specific @/entities/_shared/token path completes the systematic refactor across the codebase.


67-69: Hook usage updated consistently.

The useFungibleToken hook maintains the same parameter structure (tokenId and optional balanceCheckAccountId), ensuring the campaign form continues to work correctly with token data.

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

61-61: LGTM! Comment style standardization improves consistency.

The changes standardize comment prefixes from *? to ** throughout the function, which improves code consistency across the donation effects files.

Also applies to: 75-75, 87-87, 113-113, 132-132, 151-151, 169-169, 223-223

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

14-14: LGTM! Hook migration improves token handling consistency.

The migration from useToken to useFungibleToken aligns with the broader refactoring to standardize fungible token data fetching across the codebase.

Also applies to: 64-64


229-232: Excellent addition for campaign transparency.

The new "Fees Avoidance Allowed" display provides valuable transparency for users to understand campaign fee policies, which aligns with the fee bypass functionality mentioned in the retrieved learnings.

src/common/types.ts (3)

30-33: LGTM! Clean addition of Cart feature flag.

The new Cart feature enum member is well-documented and follows the existing pattern for feature flags.


51-53: LGTM! Useful type alias for contract operations.

The ByContractAccountId type provides consistent typing for objects that contain contract account IDs, improving type safety across the codebase.


99-101: LGTM! Clean type definition for live update control.

The LiveUpdateParams type supports enhanced SWR hook configurations for controlling revalidation behavior, which aligns with the broader hook improvements mentioned in the AI summary.

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

69-69: LGTM! Comment style standardization improves consistency.

The changes standardize comment prefixes from *? to ** throughout the function, maintaining consistency with the direct donation effects file and improving overall code readability.

Also applies to: 83-83, 95-95, 109-109, 136-136, 155-155, 174-174, 192-192, 210-210, 265-265

src/features/profile-configuration/models/types.ts (1)

1-7: Excellent implementation of schema-based type definitions.

This file demonstrates best practices by deriving TypeScript types directly from JSON schemas using the FromSchema utility. This approach ensures type safety and maintains a single source of truth for validation rules and type definitions.

src/common/_config/production.env-config.ts (2)

68-68: Feature flag activation aligns with PR objectives.

Enabling ProfileConfiguration in production is consistent with the staging-to-main migration and the extensive profile configuration refactoring in this PR.


89-93: Cart feature flag properly introduced as disabled.

Good practice to add the feature flag in a disabled state for controlled rollout.

src/entities/_shared/account/components/AccountFollowStats.tsx (3)

11-17: Excellent defensive programming with default empty arrays.

Providing default empty arrays prevents potential runtime errors and makes the component more robust.


19-22: Good memoization of URL construction.

Properly memoized with the correct dependency array to prevent unnecessary recalculations.


26-31: Improved UX with conditional rendering and functional links.

The conditional rendering based on array length prevents showing "0 Followers/Following" and the actual Near Social URLs provide functional navigation. Opening in new tabs (target="_blank") is appropriate for external links.

Also applies to: 33-38

src/common/services/pinata/hooks.ts (2)

48-51: Clean simplification to single-expression callback.

The refactoring maintains the same functionality while being more concise.


53-53: Consistent pattern for new file buffer handler.

The new handleFileBufferChange follows the same pattern as the existing callback and is properly included in the return object.

Also applies to: 57-57

src/common/ui/form/components/text.tsx (2)

25-25: Good addition of inputExtension to classNames type.

This enables flexible styling of the input extension element.


90-93: Excellent migration from UnoCSS un- attributes to standard className.*

The use of the cn utility to combine default styles with optional custom styles is the correct approach. The memoization dependency array properly includes classNames?.inputExtension since it now affects the rendered output.

Also applies to: 103-103

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

3-4: LGTM! Good integration of feature flags and contract hooks.

The addition of FEATURE_REGISTRY and donationContractHooks imports supports the new feature flag-driven UI behavior and donation configuration loading states.


44-45: LGTM! Proper loading state management.

The donation configuration hook provides both loading state and data, enabling proper UI state management during async operations.


118-125: LGTM! Feature flag integration is correctly implemented.

The "Add to cart" button is properly controlled by the FEATURE_REGISTRY.Cart.isEnabled flag, allowing for controlled feature rollout.


128-140: LGTM! Good loading state UX pattern.

The conditional rendering with Skeleton during donation config loading provides better user experience by showing a placeholder instead of a potentially broken state.

src/entities/_shared/account/components/AccountFollowButton.tsx (2)

26-27: LGTM! Simplified state management.

Removing the loading and validating state tracking for followed accounts simplifies the component logic while maintaining functionality.


78-84: LGTM! Streamlined loading condition and styling.

The loading condition is now focused solely on the follower list state, and the button styling is simplified. This reduces complexity while maintaining the essential functionality.

src/common/constants.ts (4)

9-9: LGTM! Framework version import for metadata.

Adding the framework version import enables version tracking in app metadata and development logging.


32-32: LGTM! Version metadata integration.

Adding version information to APP_METADATA under the other property provides useful version tracking for the application.

Also applies to: 48-48


175-175: LGTM! Updated deprecation notice.

The deprecation comment correctly reflects the migration to useFungibleTokenAllowlist hooks, aligning with the broader token hook refactoring in this PR.


204-212: LGTM! Useful development information.

The ASCII art banner with version information provides helpful feedback during application startup.

src/common/contracts/tokens/non-fungible/index.ts (1)

1-7: LGTM! Well-structured module organization.

The barrel export pattern with clear namespacing (nftContractClient, nftContractHooks) provides organized access to NFT contract functionality. The type re-exports and interface exports maintain proper TypeScript support.

src/common/api/coingecko/hooks.ts (2)

8-12: LGTM! Consistent with modern SWR patterns.

The migration from disabled to enabled parameter follows the established pattern across the codebase and aligns with the retrieved learning about using conditional activation for SWR hooks. The logic correctly prevents API calls when enabled is false.


21-26: Inline SWR configuration is appropriate.

The inline SWR configuration replacing CONTRACT_SWR_CONFIG maintains the same revalidation behavior while being explicit about the settings. This approach is consistent with other hooks in the codebase that have been updated in this PR.

src/common/api/near-social-indexer/hooks.ts (1)

13-18: Ensure nearSocialClient.keys returns the expected account-ID list

Before approving this change, please verify that:

  • In src/common/api/near-social-indexer/hooks.ts (around lines 13–18), the call
    nearSocialClient.keys({ keys, valuesOnly: true })
    indeed returns an object whose keys are the follower account IDs you need.
  • Object.keys(result) produces the same array of IDs that the previous post‐based call returned.
  • Performance (latency and payload size) is at least as good as before.

–– No other nearSocialClient.keys usages were found in the repo, so confirm this shape via documentation or a quick unit test.

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

13-14: LGTM! Import changes align with component updates.

The import changes correctly remove TextAreaField and add RichTextEditor to support the rich text editing functionality.


18-18: Consistent with token hook refactoring.

The change from useToken to useFungibleToken aligns with the broader refactoring across the codebase to distinguish between fungible and non-fungible token hooks.


293-302: Rich text editor integration is well implemented.

The RichTextEditor integration correctly:

  • Binds to the form's description value
  • Uses setValue with validation trigger
  • Includes character limit (250)
  • Handles error display from form state
  • Maintains proper styling

The implementation follows React Hook Form patterns and provides a better user experience compared to the plain text area.


447-447: Minor grammatical improvement.

The apostrophe change from a typographic apostrophe to a standard apostrophe improves text consistency.


513-513: Label improvement enhances clarity.

The change from "Bypass Fees" to "Fee Exemption" provides clearer terminology for users.

src/common/ui/layout/components/molecules/multi-select.tsx (5)

68-70: Dependency array fix is essential.

Adding onValueChange to the dependency array is crucial for the callback to update when the prop changes. This prevents stale closure issues and ensures the component responds correctly to prop updates.


118-120: Comprehensive dependency array prevents stale closures.

The addition of dir, inputValue.length, and onValueChange to the dependency array ensures the keyboard handler updates when any of these values change, preventing stale closure bugs and ensuring proper reactive behavior.


137-137: Styling refinement improves layout.

Removing space-y-2 from the Command component's className suggests a more refined spacing approach, likely handled by child components instead of the parent container.


160-160: Improved trigger styling.

The updated styling changes:

  • border-inputborder-neutral-300 (more specific color)
  • rounded-lgrounded-md (slightly less rounded)
  • p-1p-2 (increased padding)
  • Removed shadow-sm (cleaner appearance)

These changes provide a more refined and consistent appearance.


241-245: Code formatting improvement.

Splitting the className string into multiple lines improves readability without changing functionality. This is a good practice for long className declarations.

src/common/contracts/social-db/hooks.ts (1)

8-34: LGTM! Well-implemented live update control.

The implementation correctly adds the live parameter to control SWR revalidation behavior. The conditional SWR configuration properly disables all revalidation triggers when live=false, allowing for static data after initial fetch, while preserving SWR's default behavior when live=true.

src/common/api/intear-token-indexer/hooks.ts (1)

9-37: LGTM! Consistent refactoring to standardize hook parameters.

The refactoring from disabled to enabled parameter makes the API more intuitive, and the addition of the live parameter follows the established pattern across other hooks. The SWR configuration correctly handles both enabled state and live update control.

src/features/profile-configuration/components/contract-modal.tsx (1)

16-17: LGTM! Consistent renaming and import updates.

The renaming from "ProfileSetup" to "ProfileConfiguration" is applied consistently across component names, types, and imports. The import change to ./editor-elements aligns with the component reorganization.

Also applies to: 20-29

src/features/profile-configuration/components/funding-sources.tsx (1)

8-8: LGTM! Consistent renaming pattern.

The renaming from "ProfileSetup" to "ProfileConfiguration" is applied consistently across type imports and component declarations, maintaining the same pattern as other components in this refactor.

Also applies to: 100-107

src/common/lib/string.ts (2)

1-7: LGTM! Proper null safety handling.

The truncate function correctly handles null/undefined values using optional chaining and provides appropriate fallback behavior.


27-33: LGTM! Simple and effective URL validation.

The isValidHttpUrl function provides a clean approach to URL validation using the native URL constructor with proper error handling.

src/entities/_shared/account/components/profile-images.tsx (3)

18-18: LGTM: Hook usage updated correctly for new data structure.

The changes properly adapt to the refactored useAccountSocialProfile hook which now returns avatar and cover objects with guaranteed .url properties. This aligns with the enhanced image resolution using useAccountSocialImageSrc.

Also applies to: 24-29


39-40: Good practice: Extracting reusable CSS class constant.

The contentClassName extraction improves code maintainability and reduces duplication.


47-47: LGTM: Cover image handling updated consistently.

The changes properly use the new cover.url property from the refactored hook, maintaining consistency with the avatar image handling.

Also applies to: 58-59

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

19-19: LGTM: Token hook migration to fungible token.

The migration from useToken to useFungibleToken aligns with the broader refactoring to use token-specific hooks with enhanced functionality.

Also applies to: 36-36


110-113: LGTM: Improved CSS class composition with cn utility.

The refactoring to use the cn utility for class name composition improves maintainability and follows the established pattern in the codebase.

Also applies to: 194-199, 224-229

src/entities/_shared/account/hooks/social-profile.ts (3)

15-16: LGTM: Enhanced hook with live update support.

The addition of the live parameter provides flexibility for real-time data updates, and the integration with the updated useSocialProfile hook is well-implemented.

Also applies to: 23-23


18-18: Improved loading state precision.

The refactored loading state logic (data === undefined && isRevalidating) provides more accurate loading indication compared to directly using the underlying hook's loading state.

Also applies to: 25-25


27-35: Excellent refactoring: Robust image resolution with guaranteed URL.

The integration of useAccountSocialImageSrc provides enhanced image handling with NFT support and guaranteed fallback URLs. The new return structure with avatar and cover objects (each with .url property) is more robust than the previous direct string approach.

Also applies to: 41-42

src/common/contracts/tokens/non-fungible/client.ts (2)

17-21: LGTM: Well-structured NFT token retrieval function.

The function follows the established pattern for contract client methods, with appropriate error handling that returns undefined on failures rather than throwing errors.


26-30: Fix the empty object type usage.

The use of {} as a type parameter should be replaced with a more specific type for better type safety.

-export const nft_metadata = ({ contractAccountId }: ByContractAccountId) =>
-  nearProtocolClient.naxiosInstance
-    .contractApi({ contractId: contractAccountId })
-    .view<{}, NonFungibleTokenContractMetadata>("nft_metadata")
-    .catch(() => undefined);
+export const nft_metadata = ({ contractAccountId }: ByContractAccountId) =>
+  nearProtocolClient.naxiosInstance
+    .contractApi({ contractId: contractAccountId })
+    .view<Record<string, never>, NonFungibleTokenContractMetadata>("nft_metadata")
+    .catch(() => undefined);

Alternatively, if no parameters are needed, consider using void:

-    .view<{}, NonFungibleTokenContractMetadata>("nft_metadata")
+    .view<void, NonFungibleTokenContractMetadata>("nft_metadata")
⛔ Skipped due to learnings
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:52-54
Timestamp: 2025-04-17T13:43:20.399Z
Learning: In the PotLock codebase, the `view` method has the signature `view<A extends {}, R>(method: string, props?: ViewMethodArgs<A>, config?: BuildViewInterfaceConfig): Promise<R>` and requires using `{}` as the first type parameter when there are no arguments, even though linters may flag this as a banned type.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/ft.ts:198-205
Timestamp: 2025-04-17T13:52:53.233Z
Learning: When working with NEAR blockchain smart contracts, they will reject transactions with incorrectly formatted amounts rather than silently processing them, providing an additional layer of safety for FT (Fungible Token) transfers.
src/features/donation/components/user-entrypoints.tsx (1)

41-42: Excellent enhancement: Flexible button customization with backward compatibility.

The extension of DonateToAccountButtonProps to include ButtonProps properties provides valuable customization options while maintaining backward compatibility through sensible defaults (variant: "standard-outline", className: "w-full").

Also applies to: 44-48, 52-56

src/features/profile-configuration/models/effects.ts (2)

18-20: Clean type migration from ProfileSetup to ProfileConfiguration.

The renaming from ProfileSetupMode/ProfileSetupInputs to ProfileConfigurationMode/ProfileConfigurationInputs is consistent with the broader refactoring across the codebase.

Also applies to: 24-25


58-85: Well-implemented conditional auto-follow logic.

The conditional inclusion of auto-follow and star functionality for new registrations is cleanly implemented using the spread operator with ternary expression. This approach ensures new users automatically follow the main Potlock account while keeping the logic contained to registration flows.

src/features/profile-configuration/components/editor-elements.tsx (2)

4-4: Excellent UI standardization with FormLabel.

The replacement of custom Label component with the standardized FormLabel from the UI library improves consistency across the application and reduces maintenance overhead.

Also applies to: 60-63, 111-114


59-92: Simplified and improved CustomInput component structure.

The refactoring removes unnecessary wrapper components while maintaining the same functionality. The direct use of styled div and FormLabel makes the component structure clearer and more maintainable.

src/common/contracts/tokens/fungible/hooks.ts (2)

13-32: Excellent modernization of SWR patterns.

The replacement of disabled with enabled (defaulting to true) and addition of the live parameter provides better control over data fetching behavior. The conditional SWR configuration correctly disables all revalidation triggers when live is false, which is perfect for static data scenarios.


19-19: Proper conditional fetching implementation.

The SWR key functions correctly return null when enabled is false or when not in a client-side environment, preventing unnecessary API calls. This follows the recommended SWR pattern for conditional fetching.

Also applies to: 40-40

src/entities/_shared/account/hooks/social-image.ts (6)

10-13: LGTM! Well-defined parameter type.

The type definition is clear and appropriately uses optional data with a mandatory fallback URL to ensure a valid result is always returned.


23-27: Verify consistent usage of NOOP_STRING for disabled SWR calls.

The hook correctly uses the enabled flag to conditionally fetch NFT data and provides fallback values. The usage of NOOP_STRING follows the pattern from retrieved learnings about SWR hooks.


29-35: LGTM! Proper NFT media URL handling with IPFS gateway support.

The implementation correctly handles both HTTP URLs and IPFS content identifiers, providing appropriate fallback to the IPFS gateway.


37-43: LGTM! Comprehensive raw image source handling.

The function properly handles different data formats (string vs object) and supports both direct URLs and IPFS CIDs with gateway URLs.


45-53: LGTM! Proper memoization with correct dependencies.

The return value is properly memoized with the right dependencies, and the fallback chain ensures a URL is always available as stated in the retrieved learnings.


16-21: No additional null-safety checks needed for nftParams

The existing expression

data !== undefined && typeof data !== "string" && "nft" in data 
  ? (data.nft ?? null) 
  : null

already handles both undefined and null cases for data.nft. Since data.nft is strongly typed as an object when present (per Image.nft?: { contractId: string; tokenId: string }), there are no other falsy values to guard against.

No changes required in src/entities/_shared/account/hooks/social-image.ts.

src/features/profile-configuration/utils/normalization.ts (2)

8-13: LGTM! Clean functional approach to linktree normalization.

The stripLinktree function uses a clean functional approach with evolve to transform social media URLs using platform-specific extractors.


15-29: LGTM! Well-structured standard profile fields handling.

The function properly handles standard NEAR Social profile fields with conditional inclusion for optional images and clean linktree processing using functional composition.

src/features/profile-configuration/models/schemas.ts (4)

3-3: LGTM! Good use of constants for validation constraints.

Replacing the hardcoded 1500 with the ACCOUNT_PROFILE_DESCRIPTION_MAX_LENGTH constant improves maintainability and consistency.


31-31: LGTM! Schema rename reflects feature evolution.

The rename from profileSetupSchema to profileConfigurationSchema aligns with the broader refactoring mentioned in the AI summary.


47-50: LGTM! Well-constrained new field addition.

The new publicGoodReason field has appropriate validation constraints (20-500 characters) and is properly marked as optional.


43-43: profileImage Optionality Verified

All usages of profileImage gracefully handle an undefined value:

  • In normalization.ts, it’s conditionally spread only when present.
  • In hooks/forms.ts, initial values may be undefined and updates use setValue appropriately.
  • In image-upload.tsx, rendering is wrapped in a truthy check before using profileImage.
  • In editor.tsx, it falls back to avatar.url via nullish coalescing.

No downstream fixes are required.

src/common/contracts/tokens/non-fungible/interfaces.ts (3)

3-66: LGTM! Comprehensive NFT metadata interface following NEP-177 standard.

The NonFungibleTokenMetadata interface is well-documented and correctly implements the NEP-177 standard with appropriate null handling for optional fields. The JSDoc comments with examples enhance code clarity.


68-108: LGTM! Complete contract metadata interface.

The NonFungibleTokenContractMetadata interface properly captures all contract-level metadata fields from the NEP-177 standard with clear documentation.


110-119: LGTM! Clean token and lookup parameter types.

The NonFungibleToken and NonFungibleTokenLookupParams types are well-structured and provide the necessary fields for token operations.

src/features/profile-configuration/components/repositories-section.tsx (1)

53-60: LGTM! Consistent renaming to ProfileConfiguration.

The component and type renaming from ProfileSetup to ProfileConfiguration is consistent with the broader refactoring effort mentioned in the AI summary.

src/features/profile-configuration/components/AddFundingSourceModal.tsx (4)

3-3: LGTM - Standardized form component usage.

The switch from CustomTextForm to TextAreaField aligns with the standardization of form components across the profile configuration feature.


16-16: LGTM - Consistent domain migration.

The type and component renaming from "ProfileSetup" to "ProfileConfiguration" is consistent with the broader refactoring effort across the feature.

Also applies to: 18-27


141-148: LGTM - Improved form validation.

The replacement of CustomTextForm with TextAreaField is good, and the addition of required and maxLength={250} props improves form validation. The className placement on the field component is appropriate.


14-14: CustomInput export verified
The CustomInput component is exported in src/features/profile-configuration/components/editor-elements.tsx at line 51, so the import path in AddFundingSourceModal.tsx is correct.

src/features/profile-configuration/components/contracts-section.tsx (3)

1-1: LGTM - Added required imports.

The addition of CSSProperties and cn utility imports are necessary for the new inline Label component implementation.

Also applies to: 17-17


23-38: LGTM - Well-implemented inline component.

The new Label component is a clean, functional implementation that properly uses the cn utility for class name handling and accepts appropriate props for styling flexibility.


19-20: LGTM - Consistent with domain migration.

The import path updates and type/component renaming from "ProfileSetup" to "ProfileConfiguration" are consistent with the broader refactoring effort.

Also applies to: 200-208

src/entities/_shared/account/constants.ts (3)

10-10: LGTM - Useful validation constant.

The ACCOUNT_PROFILE_DESCRIPTION_MAX_LENGTH constant provides a centralized limit that can be used across the profile configuration feature for consistent validation.


12-20: LGTM - Migration to decentralized hosting.

The switch from local asset URLs to IPFS-hosted placeholder images aligns with the decentralized approach. Commenting out the old constants while keeping them provides good migration documentation.


31-34: LGTM - Improved URL pattern validation.

The URL pattern updates are excellent improvements:

  • Twitter pattern now supports both x.com and twitter.com domains
  • Telegram pattern correctly uses t.me instead of t.com
  • Website pattern is simplified and more flexible

These changes will better handle real-world social media URLs.

src/features/profile-configuration/components/image-upload.tsx (5)

1-12: LGTM - Well-structured imports.

The imports are properly organized and include all necessary dependencies for the component functionality.


14-27: LGTM - Clean component interface.

The props interface is well-defined using Pick to extract relevant fields from ProfileConfigurationInputs, and the callback functions provide clear contracts for handling uploads.


30-52: LGTM - Proper upload handling.

The upload success callbacks are well-implemented with appropriate toast notifications and proper dependency arrays in the useCallback hooks.


55-91: LGTM - Responsive background image section.

The background image container with overlay button is well-implemented with:

  • Proper responsive classes using max-md: breakpoints
  • Conditional rendering for existing images
  • Loading states with spinner
  • Accessible file input overlay

93-139: LGTM - Well-styled profile image section.

The profile image section is properly implemented with:

  • Circular styling with proper shadows
  • Proper positioning and overlay button
  • Consistent loading states
  • Good accessibility with file input handling
src/features/donation/components/single-recipient-allocation.tsx (6)

6-6: LGTM - Import cleanup.

The import update appears to remove unused imports while keeping the necessary Pot type.


26-27: LGTM - Consistent with architectural migration.

The switch from useAccount (indexer) to useAccountSocialProfile and from useToken to useFungibleToken aligns with the broader refactoring effort to use social profiles and standardized token hooks.


50-54: LGTM - Improved hook usage and clarity.

The updated hook calls with clearer variable names (isRecipientProfileLoading, recipientProfile, recipientProfileError) improve code readability. The hook parameters remain consistent with their previous usage patterns.

Also applies to: 56-62


93-93: LGTM - Consistent loading state updates.

The loading state references have been properly updated to use isRecipientProfileLoading throughout the component, maintaining consistency with the new hook variable naming.

Also applies to: 110-110, 126-126


155-155: LGTM - Updated error handling and profile usage.

The error handling and profile name display have been properly updated to use the social profile data structure, maintaining the same functionality with the new data source.

Also applies to: 159-159, 167-167


200-200: LGTM - Consistent prop naming.

The change from hideZeroBalanceOptions to hideBalances aligns with similar updates across other donation components, maintaining consistency in the TokenSelector API.

src/entities/_shared/token/hooks/fungible.ts (4)

12-12: LGTM!

The import of LiveUpdateParams type aligns with the broader refactoring pattern across the codebase.


16-16: LGTM!

The hook rename from useTokenAllowlist to useFungibleTokenAllowlist and parameter type change to ConditionalActivation improve clarity and consistency.


35-40: LGTM!

The hook rename to useFungibleToken and addition of the live parameter from LiveUpdateParams are well-implemented. The default value of false for live ensures backward compatibility.


49-49: Consistent implementation of the enabled pattern

All the enabled conditions have been correctly updated to use the new pattern, properly combining the enabled parameter with token ID validity checks and the live flag where applicable. This standardizes the enabling logic across all data-fetching hooks.

Also applies to: 57-57, 65-67, 75-76, 85-86, 95-96

src/common/ui/form/components/richtext.tsx (1)

1-331: Well-implemented rich text editor with comprehensive features

The implementation is thorough with proper debouncing, character limit enforcement, and cleanup logic. The component follows React best practices and integrates well with the form system.

src/common/blockchains/near-protocol/hooks.ts (3)

2-2: LGTM!

The imports are properly updated to include necessary types and constants for the refactored hooks.

Also applies to: 6-6, 11-11


22-24: LGTM!

The hook signature update to use ConditionalActivation with enabled parameter aligns with the codebase-wide pattern.


39-64: Well-implemented live update support

The useViewAccount hook correctly implements:

  • The enabled pattern with IS_CLIENT check for client-only fetching
  • Live update control through SWR configuration
  • Proper TypeScript typing with SWRResponse<AccountView, Error>
src/features/profile-configuration/hooks/forms.ts (4)

16-28: LGTM!

The type rename from ProfileSetupFormParams to ProfileFormParams and hook rename to useProfileForm align with the domain terminology update.


35-35: Good addition of live updates

Adding live: true to useAccountSocialProfile enables real-time social profile updates, improving user experience.


41-42: NFT-aware image handling

The conditional logic avatar.isNft ? undefined : avatar.url properly handles NFT profile images by omitting URLs when the image is an NFT. This aligns with the enhanced image handling capabilities.


51-74: Consistent JSON parsing for array fields

All array fields (categories, teamMembers, smartContracts, fundingSources, githubRepositories) are consistently parsed from JSON strings. Good defensive programming with the undefined checks.

src/features/profile-configuration/components/editor.tsx (3)

28-39: LGTM!

The component and type renames from "ProfileSetup" to "ProfileConfiguration" maintain consistency with the domain terminology update.


41-41: Good use of live updates

Using useAccountSocialProfile with live: true ensures the avatar and cover images stay synchronized with the latest data.


159-166: Improved form field consistency

The switch from custom components to standard form components (TextField, TextAreaField) improves consistency across the application.

Also applies to: 181-192

src/features/profile-configuration/models/deprecated.ts (2)

1-4: Consider removing this deprecated file from the PR.

This file is explicitly marked as deprecated and intended for reference only. Including deprecated reference code in a production release PR may not be appropriate, especially with the TODO comment indicating it should be removed before release.

Should this deprecated reference file be included in this staging-to-main PR, or should it be removed as indicated by the TODO comment?


5-8: Imports are appropriately structured.

The imports correctly reference the new type definitions from the profile configuration module, maintaining consistency with the refactored system.

Comment on lines 5 to 10
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { useToken } from "@/entities/_shared/token";
import { useFungibleToken } from "@/entities/_shared/token";

/**
* @deprecated Use `data.usdPrice` from {@link useToken}({ tokenId: NATIVE_TOKEN_ID })
* @deprecated Use `data.usdPrice` from {@link useFungibleToken}({ tokenId: NATIVE_TOKEN_ID })
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove the unused useFungibleToken import – it will break builds when noUnusedLocals is enabled.

// eslint-disable-next-line @typescript-eslint/no-unused-vars suppresses the ESLint warning, but TypeScript’s noUnusedLocals (commonly enabled in this repo) will still fail the compilation because the symbol is never referenced.
The import is only needed for the JSDoc link, which can be resolved without an actual value-level import.

-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { useFungibleToken } from "@/entities/_shared/token";
+/**
+ * @deprecated Use `data.usdPrice` from
+ * {@link import("@/entities/_shared/token").useFungibleToken}({ tokenId: NATIVE_TOKEN_ID })
+ */

This keeps the documentation link intact and avoids the unused-import error.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/entities/_shared/token/hooks/_deprecated.ts around lines 5 to 10, the
import of useFungibleToken is unused and will cause build failures with
noUnusedLocals enabled. Remove the actual import statement and instead use a
TypeScript type-only import or a JSDoc import syntax that references
useFungibleToken purely for documentation purposes, so the link in the JSDoc
remains but no runtime import is included.

Comment on lines +164 to +175
<div
className="prose prose-sm max-w-none"
dangerouslySetInnerHTML={{
__html: campaign?.description ?? "",
}}
onClick={(event) => {
// Prevent navigation when clicking on links
if (event.target instanceof HTMLAnchorElement) {
event.stopPropagation();
}
}}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Security concern: Validate and sanitize HTML content before rendering.

Using dangerouslySetInnerHTML without proper content sanitization can expose users to XSS attacks. Ensure that the campaign description content is properly sanitized before rendering.

Consider implementing HTML sanitization:

+import DOMPurify from 'dompurify';

 <div
   className="prose prose-sm max-w-none"
   dangerouslySetInnerHTML={{
-    __html: campaign?.description ?? "",
+    __html: DOMPurify.sanitize(campaign?.description ?? ""),
   }}
   onClick={(event) => {
     // Prevent navigation when clicking on links
     if (event.target instanceof HTMLAnchorElement) {
       event.stopPropagation();
     }
   }}
 />
🧰 Tools
🪛 Biome (1.9.4)

[error] 166-166: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🤖 Prompt for AI Agents
In src/entities/campaign/components/CampaignSettings.tsx around lines 164 to
175, the campaign description is rendered using dangerouslySetInnerHTML without
sanitization, which risks XSS attacks. To fix this, sanitize the
campaign.description content before passing it to __html using a trusted HTML
sanitizer library. This ensures any malicious scripts or unsafe HTML are removed
before rendering.

Comment on lines +75 to +93
<div
className="prose prose-sm max-w-none overflow-hidden"
style={{
display: "-webkit-box",
WebkitLineClamp: 3,
WebkitBoxOrient: "vertical",
overflow: "hidden",
textOverflow: "ellipsis",
}}
dangerouslySetInnerHTML={{
__html: data.description ?? "",
}}
onClick={(event) => {
// Prevent navigation when clicking on links
if (event.target instanceof HTMLAnchorElement) {
event.stopPropagation();
}
}}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Address XSS vulnerability in HTML rendering.

The use of dangerouslySetInnerHTML with user-provided campaign descriptions creates a potential XSS attack vector. Campaign descriptions could contain malicious scripts that would execute in users' browsers.

Consider these solutions:

  1. Recommended: Use a HTML sanitization library like DOMPurify:
+import DOMPurify from 'dompurify';

 <div
   className="prose prose-sm max-w-none overflow-hidden"
   style={{
     display: "-webkit-box",
     WebkitLineClamp: 3,
     WebkitBoxOrient: "vertical",
     overflow: "hidden",
     textOverflow: "ellipsis",
   }}
   dangerouslySetInnerHTML={{
-    __html: data.description ?? "",
+    __html: DOMPurify.sanitize(data.description ?? ""),
   }}
   onClick={(event) => {
     if (event.target instanceof HTMLAnchorElement) {
       event.stopPropagation();
     }
   }}
 />
  1. Alternative: Create a safe HTML renderer component that sanitizes content before rendering.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div
className="prose prose-sm max-w-none overflow-hidden"
style={{
display: "-webkit-box",
WebkitLineClamp: 3,
WebkitBoxOrient: "vertical",
overflow: "hidden",
textOverflow: "ellipsis",
}}
dangerouslySetInnerHTML={{
__html: data.description ?? "",
}}
onClick={(event) => {
// Prevent navigation when clicking on links
if (event.target instanceof HTMLAnchorElement) {
event.stopPropagation();
}
}}
/>
// At the top of the file
import DOMPurify from 'dompurify';
// … later in your JSX …
<div
className="prose prose-sm max-w-none overflow-hidden"
style={{
display: "-webkit-box",
WebkitLineClamp: 3,
WebkitBoxOrient: "vertical",
overflow: "hidden",
textOverflow: "ellipsis",
}}
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(data.description ?? ""),
}}
onClick={(event) => {
// Prevent navigation when clicking on links
if (event.target instanceof HTMLAnchorElement) {
event.stopPropagation();
}
}}
/>
🧰 Tools
🪛 Biome (1.9.4)

[error] 84-84: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🤖 Prompt for AI Agents
In src/entities/campaign/components/CampaignCarouselItem.tsx around lines 75 to
93, the use of dangerouslySetInnerHTML with user-provided campaign descriptions
introduces an XSS vulnerability. To fix this, integrate a HTML sanitization
library such as DOMPurify to sanitize the description content before setting it
as innerHTML. Replace the direct assignment of data.description with the
sanitized version to ensure any malicious scripts are removed before rendering.

Comment on lines 15 to 25
export const truncateHtml = (htmlContent: string, maxLength: number): string => {
if (!htmlContent) return "";

if (input.length <= maxLength) {
return input;
}
// Create a temporary div to parse HTML and get text content
const tempDiv = document.createElement("div");
tempDiv.innerHTML = htmlContent;
const textContent = tempDiv.textContent || "";

return input.substring(0, maxLength - 3) + "...";
// Use the regular truncate function on the plain text
return truncate(textContent, maxLength);
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Consider SSR compatibility for HTML parsing.

The truncateHtml function uses document.createElement which will fail in server-side rendering environments since document is not available.

Consider using a server-safe HTML parser or add environment checks:

export const truncateHtml = (htmlContent: string, maxLength: number): string => {
  if (!htmlContent) return "";
  
+ // Check if running in browser environment
+ if (typeof document === 'undefined') {
+   // Fallback: simple regex-based tag removal (less robust but SSR-safe)
+   const textContent = htmlContent.replace(/<[^>]*>/g, '');
+   return truncate(textContent, maxLength);
+ }

  // Create a temporary div to parse HTML and get text content
  const tempDiv = document.createElement("div");
  tempDiv.innerHTML = htmlContent;
  const textContent = tempDiv.textContent || "";

  // Use the regular truncate function on the plain text
  return truncate(textContent, maxLength);
};

Alternatively, consider using a library like html-to-text or cheerio for more robust and SSR-compatible HTML parsing.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const truncateHtml = (htmlContent: string, maxLength: number): string => {
if (!htmlContent) return "";
if (input.length <= maxLength) {
return input;
}
// Create a temporary div to parse HTML and get text content
const tempDiv = document.createElement("div");
tempDiv.innerHTML = htmlContent;
const textContent = tempDiv.textContent || "";
return input.substring(0, maxLength - 3) + "...";
// Use the regular truncate function on the plain text
return truncate(textContent, maxLength);
};
export const truncateHtml = (htmlContent: string, maxLength: number): string => {
if (!htmlContent) return "";
// Check if running in browser environment
if (typeof document === 'undefined') {
// Fallback: simple regex-based tag removal (less robust but SSR-safe)
const textContent = htmlContent.replace(/<[^>]*>/g, '');
return truncate(textContent, maxLength);
}
// Create a temporary div to parse HTML and get text content
const tempDiv = document.createElement("div");
tempDiv.innerHTML = htmlContent;
const textContent = tempDiv.textContent || "";
// Use the regular truncate function on the plain text
return truncate(textContent, maxLength);
};
🤖 Prompt for AI Agents
In src/common/lib/string.ts around lines 15 to 25, the truncateHtml function
uses document.createElement which breaks in server-side rendering environments
due to the absence of the document object. To fix this, replace the DOM-based
HTML parsing with a server-safe approach such as using a library like
html-to-text or cheerio to extract text content from HTML. Alternatively, add
environment checks to ensure the code only runs in the browser, but using a
dedicated SSR-compatible HTML parser is preferred for robustness.

Comment on lines +63 to 83
<div className="h-[100px]">
<div
className="prose prose-sm max-w-none overflow-hidden"
style={{
display: "-webkit-box",
WebkitLineClamp: 3,
WebkitBoxOrient: "vertical",
overflow: "hidden",
textOverflow: "ellipsis",
}}
dangerouslySetInnerHTML={{
__html: data.description ?? "",
}}
onClick={(event) => {
// Prevent navigation when clicking on links
if (event.target instanceof HTMLAnchorElement) {
event.stopPropagation();
}
}}
/>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Address XSS vulnerability in HTML rendering.

Using dangerouslySetInnerHTML without proper sanitization exposes users to XSS attacks. The campaign description content should be sanitized before rendering.

Consider implementing HTML sanitization:

- dangerouslySetInnerHTML={{
-   __html: data.description ?? "",
- }}
+ dangerouslySetInnerHTML={{
+   __html: sanitizeHtml(data.description ?? ""),
+ }}

The click handling to prevent navigation on anchor elements is well implemented.

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Biome (1.9.4)

[error] 73-73: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🤖 Prompt for AI Agents
In src/entities/campaign/components/CampaignCard.tsx around lines 63 to 83, the
use of dangerouslySetInnerHTML to render campaign descriptions introduces an XSS
vulnerability because the HTML content is not sanitized. To fix this, sanitize
the data.description content before passing it to dangerouslySetInnerHTML using
a library like DOMPurify or a similar HTML sanitizer to ensure any malicious
scripts are removed while preserving safe HTML formatting.

import { NATIVE_TOKEN_ID } from "@/common/constants";
import { Campaign } from "@/common/contracts/core/campaigns";
import { truncate } from "@/common/lib";
import { truncateHtml } from "@/common/lib";
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify HTML sanitization for XSS protection.

The import of truncateHtml suggests HTML content processing, but without seeing the implementation, ensure this utility properly sanitizes HTML to prevent XSS attacks.


🏁 Script executed:

#!/bin/bash
# Description: Check if truncateHtml utility includes HTML sanitization

# Search for the truncateHtml implementation
ast-grep --pattern 'export const truncateHtml = $_'
ast-grep --pattern 'export function truncateHtml($_) { $$$ }'

# Look for HTML sanitization libraries being used
rg -A 5 "dompurify|xss|sanitize"

Length of output: 2735


🏁 Script executed:

#!/bin/bash
# Inspect usage of truncateHtml and dangerouslySetInnerHTML in CampaignCard.tsx
rg -n "truncateHtml" -C 5 src/entities/campaign/components/CampaignCard.tsx
rg -n "dangerouslySetInnerHTML" -C 5 src/entities/campaign/components/CampaignCard.tsx

Length of output: 1206


🏁 Script executed:

#!/bin/bash
# Display CampaignCard.tsx around the HTML rendering block
sed -n '1,200p' src/entities/campaign/components/CampaignCard.tsx

Length of output: 4137


Ensure HTML content is properly sanitized before rendering

The CampaignCard component uses dangerouslySetInnerHTML with raw data.description (and never actually calls the imported truncateHtml). That import only strips HTML to plain text—it does not sanitize—and currently no sanitizer is applied, leaving an XSS hole.

• File: src/entities/campaign/components/CampaignCard.tsx
Lines ~73–75:

dangerouslySetInnerHTML={{
  __html: data.description ?? "",
}}

• Actions:

  • Integrate a robust HTML sanitizer (e.g. DOMPurify or sanitize-html) and apply it to data.description before passing to __html.
  • Remove the unused truncateHtml import if you’re not using it here.
  • Add unit or snapshot tests to verify dangerous tags/attributes are stripped.
🤖 Prompt for AI Agents
In src/entities/campaign/components/CampaignCard.tsx around lines 6 and 73-75,
the component uses dangerouslySetInnerHTML with raw data.description without
sanitization, creating an XSS vulnerability. Fix this by integrating a robust
HTML sanitizer like DOMPurify or sanitize-html, sanitize data.description before
passing it to __html, remove the unused truncateHtml import, and add unit or
snapshot tests to confirm dangerous HTML tags and attributes are properly
stripped.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 54a2b0f and 06517a7.

📒 Files selected for processing (3)
  • src/entities/_shared/account/components/card.tsx (1 hunks)
  • src/entities/_shared/account/components/profile-images.tsx (1 hunks)
  • src/pages/index.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/entities/_shared/account/components/profile-images.tsx
🧰 Additional context used
🧠 Learnings (2)
src/entities/_shared/account/components/card.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/pages/index.tsx (4)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.
🧬 Code Graph Analysis (1)
src/entities/_shared/account/components/card.tsx (1)
src/entities/_shared/account/components/profile-images.tsx (2)
  • AccountProfileCover (45-72)
  • AccountProfilePicture (15-34)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build (20.x)
🔇 Additional comments (5)
src/entities/_shared/account/components/card.tsx (2)

61-61: LGTM! Live profile cover updates enabled.

The addition of the live prop enables real-time updates for the profile cover image, which aligns with the PR's objective to add live data support.


66-66: LGTM! Live profile picture updates enabled.

The addition of the live prop enables real-time updates for the profile picture, maintaining consistency with the cover image implementation.

src/pages/index.tsx (3)

15-15: LGTM! Necessary import for loading states.

The Skeleton import is required for the new loading placeholders in the GeneralStats component.


42-46: Good UX improvement, but verify skeleton classes.

The conditional rendering with skeleton loading state is a great UX improvement. However, the skeleton uses non-standard Tailwind classes (h-5.5, w-29) that may not exist in standard Tailwind CSS.

Consider using standard Tailwind height/width classes:

-<Skeleton className="h-5.5 w-29" />
+<Skeleton className="h-6 w-28" />

83-83: Good typography improvement.

The change from leading-none to leading-[1.1] provides slightly better line spacing and improves readability of the heading text.

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: 2

♻️ Duplicate comments (2)
src/entities/campaign/components/CampaignBanner.tsx (1)

146-157: Critical security issue: Use Markdown instead of HTML.

This implementation violates the established pattern of using Markdown for rich text content. As previously stated by the team, HTML rendering is not allowed due to XSS risks.

Replace the HTML rendering with a Markdown parser:

+import { marked } from 'marked';

-<div
-  className="prose prose-sm max-w-none"
-  dangerouslySetInnerHTML={{
-    __html: campaign?.description ?? "",
-  }}
-  onClick={(event) => {
-    // Prevent navigation when clicking on links
-    if (event.target instanceof HTMLAnchorElement) {
-      event.stopPropagation();
-    }
-  }}
-/>
+<div
+  className="prose prose-sm max-w-none"
+  dangerouslySetInnerHTML={{
+    __html: marked(campaign?.description ?? ""),
+  }}
+/>
src/features/profile-configuration/hooks/forms.ts (1)

46-48: Verify stripLinktree utility behavior

The stripLinktree utility is applied to social links. Ensure this utility correctly extracts and normalizes the social media usernames/handles from potential Linktree URLs.

Run the following script to verify the stripLinktree implementation:

#!/bin/bash
# Description: Verify the stripLinktree implementation and its usage

# Check the stripLinktree implementation
ast-grep --pattern 'export const stripLinktree = $_'

# Check for test coverage of stripLinktree
fd -e test.ts -e spec.ts | xargs rg -l "stripLinktree" -A 5
🧹 Nitpick comments (4)
src/entities/campaign/components/CampaignBanner.tsx (1)

253-281: Consider extracting complex conditional logic.

While the logic is correct, the complex conditional would benefit from extraction into descriptive variables for better readability.

+const shouldShowEscrowProcessing = !isProcessingHooksLoading &&
+  hasEscrowedDonations &&
+  isNonNullish(campaign?.min_amount) &&
+  raisedAmountFloat >= minAmountFloat;
+
+const shouldShowRefundOption = !isProcessingHooksLoading &&
+  isDonationRefundsProcessed &&
+  campaign?.end_ms &&
+  campaign?.end_ms < Temporal.Now.instant().epochMilliseconds &&
+  raisedAmountFloat < minAmountFloat;
+
+const shouldShowDonationUI = !isProcessingHooksLoading &&
+  !shouldShowEscrowProcessing &&
+  !shouldShowRefundOption;

-{!isProcessingHooksLoading &&
-  (!hasEscrowedDonations ||
-    !isNonNullish(campaign?.min_amount) ||
-    raisedAmountFloat < minAmountFloat) &&
-  (!isDonationRefundsProcessed ||
-    !campaign?.end_ms ||
-    campaign?.end_ms >= Temporal.Now.instant().epochMilliseconds ||
-    raisedAmountFloat >= minAmountFloat) && (
+{shouldShowDonationUI && (
src/features/profile-configuration/components/AddFundingSourceModal.tsx (1)

1-1: Remove unused import

useEffect is imported but not used in this component.

-import { useCallback, useEffect } from "react";
+import { useCallback } from "react";
src/features/profile-configuration/components/repositories-section.tsx (2)

10-25: Remove unused function extractRepositoryPath.

This utility function is defined but never used in the component. Consider removing it to reduce code clutter, or utilize it in the input handling logic if it was intended to be used.


88-99: Consider simplifying the conditional logic.

The handleChange function has nested conditions that could be simplified for better readability.

  const handleChange = useCallback(
    (index: number, value: string) => {
-      if (onUpdate) {
-        onUpdate(index, value);
-      } else if (onChange && values) {
-        const updatedRepos = [...values];
-        updatedRepos[index] = value;
-        onChange(updatedRepos);
-      }
+      if (onUpdate) {
+        onUpdate(index, value);
+        return;
+      }
+      
+      if (onChange && values) {
+        const updatedRepos = [...values];
+        updatedRepos[index] = value;
+        onChange(updatedRepos);
+      }
    },
    [onChange, onUpdate, values],
  );
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 5aa6c42 and 68b5c29.

📒 Files selected for processing (7)
  • src/entities/campaign/components/CampaignBanner.tsx (5 hunks)
  • src/features/profile-configuration/components/AddFundingSourceModal.tsx (3 hunks)
  • src/features/profile-configuration/components/contracts-section.tsx (4 hunks)
  • src/features/profile-configuration/components/editor.tsx (8 hunks)
  • src/features/profile-configuration/components/funding-sources.tsx (3 hunks)
  • src/features/profile-configuration/components/repositories-section.tsx (1 hunks)
  • src/features/profile-configuration/hooks/forms.ts (4 hunks)
🧰 Additional context used
🧠 Learnings (6)
src/features/profile-configuration/components/AddFundingSourceModal.tsx (5)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation.tsx:50-56
Timestamp: 2025-05-13T04:00:23.459Z
Learning: In react-hook-form, `form.watch()` method does trigger component re-renders when the watched field values change, similar to `useWatch()`. The main difference is that `useWatch()` is more granular and only re-renders the component it's used in, while `form.watch()` may cause the parent component to re-render.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:55:21.902Z
Learning: The toast component from shadcn/ui is imported from "@/hooks/use-toast". For success messages, use a simple toast with description. For error states, use the "destructive" variant.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:43:02.493Z
Learning: For error handling in the UI, use the `useToast` hook from the UI kit instead of Redux dispatch, as the codebase aims to minimize Redux usage.
src/features/profile-configuration/components/funding-sources.tsx (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
src/entities/campaign/components/CampaignBanner.tsx (7)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#424
File: src/pages/index.tsx:52-56
Timestamp: 2025-07-02T13:31:11.268Z
Learning: In src/pages/index.tsx, the donation count (total_donations_count) is intentionally displayed with a dollar sign prefix for UI consistency, even though it represents a count rather than a currency amount. This is the intended behavior.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which manages loading state and provides success/error callbacks for UI feedback.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides comprehensive error handling including loading state management, success/error callbacks, error logging, and proper cleanup.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides `onPublishSuccess` and `onPublishError` callbacks for proper error handling in the UI layer.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/features/profile-configuration/hooks/forms.ts (4)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation.tsx:50-56
Timestamp: 2025-05-13T04:00:23.459Z
Learning: In react-hook-form, `form.watch()` method does trigger component re-renders when the watched field values change, similar to `useWatch()`. The main difference is that `useWatch()` is more granular and only re-renders the component it's used in, while `form.watch()` may cause the parent component to re-render.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.
src/features/profile-configuration/components/contracts-section.tsx (1)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
src/features/profile-configuration/components/editor.tsx (3)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/features/profile-configuration/components/AddFundingSourceModal.tsx:141-148
Timestamp: 2025-06-25T12:24:17.258Z
Learning: TextAreaField component in src/common/ui/form/components/textarea.tsx does not accept an error prop. It handles validation errors automatically through FormMessage when used within FormField from react-hook-form.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/components/group-allocation.tsx:50-56
Timestamp: 2025-05-13T04:00:23.459Z
Learning: In react-hook-form, `form.watch()` method does trigger component re-renders when the watched field values change, similar to `useWatch()`. The main difference is that `useWatch()` is more granular and only re-renders the component it's used in, while `form.watch()` may cause the parent component to re-render.
🧬 Code Graph Analysis (3)
src/features/profile-configuration/components/AddFundingSourceModal.tsx (2)
src/features/profile-configuration/models/types.ts (1)
  • AddFundingSourceInputs (7-7)
src/features/profile-configuration/hooks/forms.ts (1)
  • useAddFundingSourceForm (280-317)
src/features/profile-configuration/hooks/forms.ts (3)
src/features/profile-configuration/models/types.ts (1)
  • AddFundingSourceInputs (7-7)
src/common/ui/form/hooks/enhanced.ts (1)
  • useEnhancedForm (86-124)
src/features/profile-configuration/models/schemas.ts (1)
  • addFundingSourceSchema (5-27)
src/features/profile-configuration/components/editor.tsx (3)
src/features/profile-configuration/models/deprecated.ts (3)
  • updateFundingSource (54-62)
  • addSmartContract (68-72)
  • removeSmartContract (74-77)
src/features/profile-configuration/components/editor-elements.tsx (2)
  • SubHeader (19-36)
  • Row (38-40)
src/features/profile-configuration/components/contracts-section.tsx (1)
  • ProfileConfigurationSmartContractsSection (202-224)
🪛 Biome (1.9.4)
src/entities/campaign/components/CampaignBanner.tsx

[error] 148-148: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🔇 Additional comments (17)
src/entities/campaign/components/CampaignBanner.tsx (4)

56-66: Good improvement on loading state handling.

Always enabling the hooks and tracking their loading states provides better UX by eliminating delays when conditions change.


89-92: Clean loading state management.

Combining the loading states prevents race conditions and ensures consistent UI behavior.


189-217: Improved conditional logic for escrow processing.

The addition of loading state checks and explicit validation of minimum amount conditions ensures the UI only shows when appropriate.


282-286: Good loading state UI.

The loading spinner provides clear feedback while the hooks are fetching data.

src/features/profile-configuration/components/funding-sources.tsx (3)

103-103: LGTM! Proper external handler delegation

The component now correctly delegates delete operations to the parent component through the onDeleteClick prop, following the established pattern for edit operations.

Also applies to: 108-108, 143-143


119-119: Good improvement on key uniqueness

Using a composite key with the index prevents React reconciliation issues when there are duplicate investor names.


139-139: Correct button type specification

Adding type="button" prevents these buttons from accidentally submitting any parent forms.

Also applies to: 143-143

src/features/profile-configuration/components/AddFundingSourceModal.tsx (2)

23-24: Well-implemented external handler pattern

The optional handler props and their conditional invocation provide good flexibility for the parent component to control add/update operations while maintaining backward compatibility.

Also applies to: 63-65, 78-80


38-47: Proper conditional default values initialization

The default values are correctly set based on whether it's in edit mode, ensuring the form is populated with existing data when editing.

src/features/profile-configuration/components/editor.tsx (2)

54-61: Excellent implementation of granular handlers

The refactoring to use specific add/update/remove handlers instead of bulk updates provides better control and clearer intent. The proper delegation of these handlers to child components maintains good separation of concerns.

Also applies to: 115-116, 224-225, 237-237, 256-257


17-17: Remove commented code instead of leaving it in

Instead of commenting out the smart contract modal import and usage, consider removing it entirely if it's no longer needed. Commented code can lead to confusion and maintenance issues.

-// import { ProfileConfigurationSmartContractModal } from "./contract-modal";

And remove lines 123-130 entirely.

Also applies to: 123-130

⛔ Skipped due to learnings
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/features/donation/components/campaign-success-share.tsx:34-42
Timestamp: 2025-05-24T02:05:25.352Z
Learning: For the PotLock project, cosmetic refactoring suggestions should be avoided during feature PRs unless they directly impact functionality or are explicitly requested by the user.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/entities/campaign/hooks/forms.ts:94-116
Timestamp: 2025-02-14T13:32:23.816Z
Learning: Error handling in the codebase is implemented at the consuming code level (UI components, etc.) rather than in the contract client layer. The contract client functions should remain focused on contract interactions without error handling logic.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
src/features/profile-configuration/components/contracts-section.tsx (2)

81-82: Well-structured handler implementation

The addition of external handlers for add and remove operations, along with proper validation and state cleanup, follows best practices. The defensive checks before invoking handlers prevent runtime errors.

Also applies to: 96-131, 133-137


212-212: Improved key uniqueness

Including the index in the key ensures React can properly track components even when contract information might be duplicated.

src/features/profile-configuration/hooks/forms.ts (3)

157-160: Good data integrity validation

The validation logic that filters out funding sources with missing required fields ensures data integrity before state updates. This prevents invalid data from being persisted.

Also applies to: 173-176, 190-193


134-150: Consistent and well-implemented list management handlers

All the new handlers follow a consistent pattern:

  • Proper state copying to avoid mutations
  • Validation triggers with shouldValidate: true
  • Clear separation between add, update, and remove operations

This provides a clean API for managing dynamic lists in the form.

Also applies to: 152-200, 202-226


284-288: Clean migration to useEnhancedForm

The migration from useForm to useEnhancedForm is properly implemented with the schema and options correctly passed through.

src/features/profile-configuration/components/repositories-section.tsx (1)

114-116: Incorrect empty state concern: Add Repository button is outside the section

The ProfileConfigurationRepositoriesSection returning null when values is empty does not block adding repositories— the “Add Repository” button is rendered unconditionally in the parent (src/features/profile-configuration/components/editor.tsx around lines 262–266). Users can always click that button to add their first repository.

No changes required here.

Likely an incorrect or invalid review comment.

Comment on lines +120 to +128
{values.map((repo, index) => (
<Repo
key={`${repo}-${index}`}
repo={repo}
index={index}
onChangeHandler={handleChange}
onRemoveHandler={handleRemove}
/>
))}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use stable keys for React list items.

Using ${repo}-${index} as a key can cause React reconciliation issues when repository values change. Consider using just the index or a stable unique identifier.

-        key={`${repo}-${index}`}
+        key={index}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{values.map((repo, index) => (
<Repo
key={`${repo}-${index}`}
repo={repo}
index={index}
onChangeHandler={handleChange}
onRemoveHandler={handleRemove}
/>
))}
{values.map((repo, index) => (
<Repo
key={index}
repo={repo}
index={index}
onChangeHandler={handleChange}
onRemoveHandler={handleRemove}
/>
))}
🤖 Prompt for AI Agents
In src/features/profile-configuration/components/repositories-section.tsx around
lines 120 to 128, the current key for the Repo components uses a template string
combining repo and index, which is unstable and can cause React reconciliation
issues. Replace the key with a stable unique identifier if available from the
repo object, such as an id or name property; if no unique identifier exists, use
only the index as the key to ensure stability during re-renders.

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: 0

🧹 Nitpick comments (6)
src/entities/_shared/account/components/AccountProfileLink.tsx (2)

6-6: Remove unused import.

The truncate function is imported but no longer used after the CSS-based truncation refactor.

-import { isEthereumAddress, truncate } from "@/common/lib";
+import { isEthereumAddress } from "@/common/lib";

40-51: Excellent CSS-based truncation implementation with good UX improvements.

The change from programmatic truncation to CSS-based truncation is well-implemented and provides several benefits:

  • Better performance by avoiding JavaScript string manipulation
  • Hover tooltips via title attribute for accessibility
  • Responsive design with conditional styling based on content length

The logic correctly handles both short and long names/IDs with appropriate styling.

Consider extracting the magic numbers as constants for better maintainability:

+const TRUNCATION_THRESHOLD = 20;
+const MAX_NAME_WIDTH = 140;
+
 <span
   className={cn(
     "font-500 text-nowrap",
-    (profile?.name ?? accountId).length > 20
-      ? "max-w-[140px] overflow-hidden text-ellipsis whitespace-nowrap"
+    (profile?.name ?? accountId).length > TRUNCATION_THRESHOLD
+      ? `max-w-[${MAX_NAME_WIDTH}px] overflow-hidden text-ellipsis whitespace-nowrap`
       : "w-fit",
     classNames?.name,
   )}
   title={profile?.name ?? accountId}
 >
   {profile?.name ?? accountId}
 </span>
src/pages/campaigns.tsx (2)

42-42: Use dynamic length calculation instead of hardcoded pagination count.

The hardcoded /6 creates a maintenance issue where this number needs to be kept in sync with the filter array length. Consider calculating this dynamically.

-          <p className="text-[18px]">{current + 1}/6</p>
+          <p className="text-[18px]">{current + 1}/{data?.filter((data) => [52, 51, 45, 41, 44, 43].includes(data?.id)).length}</p>

Or better yet, extract the featured campaign IDs to a constant and use its length:

+const FEATURED_CAMPAIGN_IDS = [52, 51, 45, 41, 44, 43];
+
 const FeaturedCampaigns = ({ data }: { data: Campaign[] }) => {
   // ...
-          <p className="text-[18px]">{current + 1}/6</p>
+          <p className="text-[18px]">{current + 1}/{FEATURED_CAMPAIGN_IDS.length}</p>

63-63: Extract featured campaign IDs to a constant for better maintainability.

The filter update looks good and aligns with the reduction from 8 to 6 featured campaigns. Consider extracting these IDs to a constant for better maintainability.

+const FEATURED_CAMPAIGN_IDS = [52, 51, 45, 41, 44, 43];
+
 const FeaturedCampaigns = ({ data }: { data: Campaign[] }) => {
   // ...
-              ?.filter((data) => [52, 51, 45, 41, 44, 43].includes(data?.id))
+              ?.filter((data) => FEATURED_CAMPAIGN_IDS.includes(data?.id))
src/entities/campaign/hooks/forms.ts (1)

298-310: Good defensive programming, but consider refinements.

The runtime validation for campaign creation response is a good defensive programming practice. However, consider these improvements:

  1. Remove the console.log statement for production
  2. Improve the type checking approach
-            // Fix: Ensure newCampaign has an id before accessing it
-            console.log(newCampaign);
-
-            if (
-              newCampaign &&
-              typeof newCampaign === "object" &&
-              "id" in newCampaign &&
-              newCampaign.id
-            ) {
-              router.push(routeSelectors.CAMPAIGN_BY_ID((newCampaign as Campaign).id));
-            } else {
-              router.push(`/campaigns`);
-            }
+            // Ensure newCampaign has a valid id before navigation
+            const isValidCampaign = (obj: unknown): obj is Campaign => {
+              return obj !== null && 
+                     typeof obj === "object" && 
+                     "id" in obj && 
+                     typeof obj.id === "number" && 
+                     obj.id > 0;
+            };
+
+            if (isValidCampaign(newCampaign)) {
+              router.push(routeSelectors.CAMPAIGN_BY_ID(newCampaign.id));
+            } else {
+              router.push(`/campaigns`);
+            }
src/common/contracts/core/campaigns/client.ts (1)

33-103: Well-structured implementation with good separation of concerns.

The refactored create_campaign function effectively adds project profile creation while maintaining backward compatibility. The conditional logic, transaction batching, and proper deposit calculations are well-implemented.

Consider these improvements for better maintainability:

  1. Extract profile creation logic to a helper function:
const createProjectProfile = (args: CampaignInputs): Transaction<object> => {
  const { project_name, project_description, owner } = args;
  
  const socialArgs: NEARSocialUserProfile = profileConfigurationInputsToSocialDbFormat({
    name: project_name!,
    description: project_description ?? "",
    categories: [],
    profileImage: ACCOUNT_PROFILE_IMAGE_PLACEHOLDER_SRC,
  });

  const depositFloat = Big(calculateDepositByDataSize(socialArgs)).add(0.1).toString();
  
  return buildTransaction("set", {
    receiverId: SOCIAL_DB_CONTRACT_ACCOUNT_ID,
    args: {
      data: {
        [owner as AccountId]: {
          profile: socialArgs,
          // ... rest of the profile structure
        },
      },
    },
    deposit: parseNearAmount(depositFloat)!,
  });
};
  1. Add comments explaining the hardcoded social profile structure:
// The index and graph sections are required for NEAR Social integration
// They establish the project's presence in the NEAR Social ecosystem
index: {
  star: { /* ... */ },
  notify: { /* ... */ },
},
graph: {
  star: { /* ... */ },
  follow: { /* ... */ },
},
  1. Make the deposit increment more explicit:
// Add 0.1 NEAR buffer for storage deposit variations
const depositFloat = Big(calculateDepositByDataSize(socialArgs)).add(0.1).toString();
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 68b5c29 and 6c73e6f.

📒 Files selected for processing (7)
  • src/common/contracts/core/campaigns/client.ts (3 hunks)
  • src/common/contracts/core/campaigns/interfaces.ts (1 hunks)
  • src/entities/_shared/account/components/AccountProfileLink.tsx (1 hunks)
  • src/entities/campaign/components/editor.tsx (6 hunks)
  • src/entities/campaign/hooks/forms.ts (4 hunks)
  • src/entities/campaign/models/schema.ts (2 hunks)
  • src/pages/campaigns.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/common/contracts/core/campaigns/interfaces.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/entities/campaign/models/schema.ts
  • src/entities/campaign/components/editor.tsx
🧰 Additional context used
🧠 Learnings (4)
src/entities/_shared/account/components/AccountProfileLink.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
src/entities/campaign/hooks/forms.ts (4)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
src/pages/campaigns.tsx (2)
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#424
File: src/pages/index.tsx:52-56
Timestamp: 2025-07-02T13:31:11.268Z
Learning: In src/pages/index.tsx, the donation count (total_donations_count) is intentionally displayed with a dollar sign prefix for UI consistency, even though it represents a count rather than a currency amount. This is the intended behavior.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
src/common/contracts/core/campaigns/client.ts (7)
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.
🧬 Code Graph Analysis (2)
src/entities/campaign/hooks/forms.ts (2)
src/pathnames.ts (1)
  • routeSelectors (19-35)
src/common/contracts/core/campaigns/interfaces.ts (1)
  • Campaign (33-51)
src/common/contracts/core/campaigns/client.ts (6)
src/features/profile-configuration/utils/normalization.ts (1)
  • profileConfigurationInputsToSocialDbFormat (15-41)
src/entities/_shared/account/constants.ts (1)
  • ACCOUNT_PROFILE_IMAGE_PLACEHOLDER_SRC (14-15)
src/common/types.ts (1)
  • AccountId (45-45)
src/common/lib/format.ts (2)
  • parseNearAmount (7-7)
  • floatToYoctoNear (31-32)
src/common/constants.ts (2)
  • PUBLIC_GOODS_REGISTRY_LIST_ID (128-128)
  • FULL_TGAS (140-140)
src/common/contracts/core/campaigns/interfaces.ts (1)
  • Campaign (33-51)
🔇 Additional comments (4)
src/entities/campaign/hooks/forms.ts (3)

34-37: LGTM! Clean extension of Values type for project metadata.

The addition of optional project_name and project_description fields to the Values type is well-structured and aligns with the campaign creation schema updates for project metadata support.


214-217: LGTM! Proper conditional inclusion of project fields.

The conditional inclusion of project_name and project_description follows the established pattern and correctly checks for both new campaign creation and field presence before including them in the arguments.


312-312: LGTM! Simplified error handling.

The removal of the unused error parameter from the catch block is a good simplification while maintaining appropriate user feedback through the toast notification.

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

1-14: LGTM! Well-organized imports for enhanced functionality.

The new imports are properly organized and support the transaction batching and profile creation functionality being added to the campaign creation flow.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 6c73e6f and 56269b6.

📒 Files selected for processing (1)
  • src/common/contracts/core/campaigns/client.ts (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
src/common/contracts/core/campaigns/client.ts (7)

Learnt from: carina-akaia
PR: #341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (src/common/contracts/core/campaigns/client.ts) should remain focused on making the calls without error handling logic.

Learnt from: carina-akaia
PR: #357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using {} as a type parameter is acceptable for the contractApi.call method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.

Learnt from: akaia-shadowfox
PR: #388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using {} as a type parameter is acceptable for the contractApi.view method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.

Learnt from: akaia-shadowfox
PR: #400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.

Learnt from: carina-akaia
PR: #365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with nearRps.txStatus in the future, so extensive refinements to the current implementation aren't necessary.

Learnt from: akaia-shadowfox
PR: #418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The useAccountSocialProfile hook in src/entities/_shared/account/hooks/social-profile.ts returns avatar and cover objects where the .url property is guaranteed to be defined. The hook uses useAccountSocialImageSrc with fallback URLs (placeholder constants) to ensure these properties are never undefined.

Learnt from: akaia-shadowfox
PR: #418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The useAccountSocialProfile hook in src/entities/_shared/account/hooks/social-profile.ts returns avatar and cover objects where the .url property is guaranteed to be defined. The hook uses useAccountSocialImageSrc with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: nftMediaSrc ?? rawImageSrc ?? fallbackUrl.

🧬 Code Graph Analysis (1)
src/common/contracts/core/campaigns/client.ts (5)
src/features/profile-configuration/utils/normalization.ts (1)
  • profileConfigurationInputsToSocialDbFormat (15-41)
src/entities/_shared/account/constants.ts (1)
  • ACCOUNT_PROFILE_IMAGE_PLACEHOLDER_SRC (14-15)
src/common/types.ts (1)
  • AccountId (45-45)
src/common/lib/format.ts (2)
  • parseNearAmount (7-7)
  • floatToYoctoNear (31-32)
src/common/constants.ts (2)
  • PUBLIC_GOODS_REGISTRY_LIST_ID (128-128)
  • FULL_TGAS (140-140)
🔇 Additional comments (3)
src/common/contracts/core/campaigns/client.ts (3)

1-14: LGTM! Imports support the enhanced functionality.

The new imports are well-organized and support the conditional campaign creation with social profile setup. All imported modules are utilized in the implementation.


33-86: Well-structured conditional campaign creation.

The function maintains backward compatibility through the conditional logic while adding enhanced project profile creation. The destructuring pattern and fallback approach are clean and maintainable.


59-78: Batched transactions and deposit constants are correct and consistent

  • PUBLIC_GOODS_REGISTRY_LIST_ID is defined as 1 in src/common/constants.ts and used uniformly across all registry calls.
  • The registry registration deposit (0.05 NEAR) and campaign creation deposit (0.021 NEAR) in src/common/contracts/core/campaigns/client.ts align with other client methods (e.g., update_campaign, delete_campaign).
  • Using contractApi.callMultiple ensures atomic execution of the social-profile → registry → campaign workflow.

No changes required—approving implementation.

Comment on lines 38 to 57
const socialArgs: NEARSocialUserProfile = profileConfigurationInputsToSocialDbFormat({
name: project_name,
description: project_description ?? "",
categories: [], // Default category for new projects
profileImage: ACCOUNT_PROFILE_IMAGE_PLACEHOLDER_SRC,
});

const depositFloat = Big(calculateDepositByDataSize(socialArgs)).add(0.1).toString();

const socialTransaction = buildTransaction("set", {
receiverId: SOCIAL_DB_CONTRACT_ACCOUNT_ID,
args: {
data: {
[args.owner as AccountId]: {
profile: socialArgs,
},
},
},
deposit: parseNearAmount(depositFloat)!,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify deposit calculation and consider configurable defaults.

The social profile creation logic is solid, but consider these improvements:

  1. The 0.1 NEAR buffer in deposit calculation appears arbitrary - ensure this is sufficient for gas costs.
  2. Empty categories array as default might not be ideal for discoverability.
  3. Consider making the placeholder image configurable rather than hardcoded.

🏁 Script executed:

#!/bin/bash
# Verify if the 0.1 NEAR buffer is documented or used elsewhere
rg -A 3 -B 3 "0\.1.*NEAR|\.add\(0\.1\)" --type ts

Length of output: 1218


Extract Magic Deposit Buffer and Externalize Defaults

The hardcoded 0.1 NEAR buffer is used in multiple places and lacks documentation. To improve maintainability and clarity, please:

  • Extract the 0.1 NEAR buffer into a named constant (e.g. DEPOSIT_BUFFER_NEAR) and document why this value was chosen.
  • Replace all occurrences of .add(0.1) with the new constant.
  • Consider making the default categories array and ACCOUNT_PROFILE_IMAGE_PLACEHOLDER_SRC configurable (via a constant or config file) to avoid magic values and improve discoverability.

Points of attention:

  • src/common/contracts/core/campaigns/client.ts: .add(0.1)
  • src/features/profile-configuration/models/effects.ts: .add(0.1)
🤖 Prompt for AI Agents
In src/common/contracts/core/campaigns/client.ts around lines 38 to 57, the
hardcoded deposit buffer value 0.1 NEAR used in the .add(0.1) call should be
extracted into a named constant like DEPOSIT_BUFFER_NEAR with a comment
explaining its purpose. Replace all .add(0.1) occurrences with this constant.
Additionally, move the default categories array and
ACCOUNT_PROFILE_IMAGE_PLACEHOLDER_SRC into configurable constants or a config
file to eliminate magic values and improve code clarity and maintainability.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 56269b6 and 88b62d6.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (5)
  • package.json (3 hunks)
  • src/common/blockchains/near-protocol/client.ts (2 hunks)
  • src/common/contracts/core/campaigns/client.ts (3 hunks)
  • src/entities/_shared/account/components/AccountProfileLink.tsx (1 hunks)
  • src/entities/campaign/components/editor.tsx (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/common/contracts/core/campaigns/client.ts
  • package.json
  • src/entities/_shared/account/components/AccountProfileLink.tsx
  • src/entities/campaign/components/editor.tsx
🧰 Additional context used
🧠 Learnings (1)
src/common/blockchains/near-protocol/client.ts (1)

Learnt from: carina-akaia
PR: #365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with nearRps.txStatus in the future, so extensive refinements to the current implementation aren't necessary.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build (20.x)
🔇 Additional comments (1)
src/common/blockchains/near-protocol/client.ts (1)

21-21: LGTM!

The Unity Wallet import follows the established pattern and is properly positioned alphabetically with other wallet selector imports.

Comment on lines 52 to 60
setupUnityWallet({
projectId: "unity-wallet",
metadata: {
name: "Potlock App",
description: "Bringing public goods funding to the table, built on NEAR",
url: "https://github.com/near/wallet-selector",
icons: ["https://avatars.githubusercontent.com/u/37784886"],
},
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update metadata URL and icons to reflect Potlock app resources.

The Unity Wallet configuration uses placeholder values that should be updated:

  1. The url currently points to the wallet-selector library repository instead of the actual Potlock app
  2. The icons array uses a generic GitHub avatar rather than the Potlock app icon

Consider updating these values to properly represent the Potlock application:

 setupUnityWallet({
   projectId: "unity-wallet",
   metadata: {
     name: "Potlock App",
     description: "Bringing public goods funding to the table, built on NEAR",
-    url: "https://github.com/near/wallet-selector",
-    icons: ["https://avatars.githubusercontent.com/u/37784886"],
+    url: "https://potlock.org", // or appropriate Potlock app URL
+    icons: ["https://potlock.org/favicon.ico"], // or appropriate Potlock app icon
   },
 }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
setupUnityWallet({
projectId: "unity-wallet",
metadata: {
name: "Potlock App",
description: "Bringing public goods funding to the table, built on NEAR",
url: "https://github.com/near/wallet-selector",
icons: ["https://avatars.githubusercontent.com/u/37784886"],
},
}),
setupUnityWallet({
projectId: "unity-wallet",
metadata: {
name: "Potlock App",
description: "Bringing public goods funding to the table, built on NEAR",
url: "https://potlock.org", // or appropriate Potlock app URL
icons: ["https://potlock.org/favicon.ico"], // or appropriate Potlock app icon
},
}),
🤖 Prompt for AI Agents
In src/common/blockchains/near-protocol/client.ts around lines 52 to 60, update
the Unity Wallet setup metadata by replacing the url with the actual Potlock app
URL instead of the wallet-selector GitHub link, and replace the icons array with
the correct Potlock app icon URL to accurately represent the application.

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: 0

🔭 Outside diff range comments (1)
src/entities/campaign/components/CampaignProgressBar.tsx (1)

185-196: Fix dependency array in titleContent useMemo

The dependency array is missing isEnded but the function references it. Also, isTimeUp is referenced but not included in dependencies.

  }, [
    amountDisplay,
-    isTimeUp,
+    isEnded,
    isTargetMet,
    raisedAmountFloat,
    minAmountFloat,
    isEscrowBalanceEmpty,
    color,
    tokenId,
    targetAmountFloat,
    token?.metadata.symbol,
  ]);
♻️ Duplicate comments (4)
src/entities/campaign/components/CampaignSettings.tsx (1)

171-182: Security concern: HTML content needs sanitization

Using dangerouslySetInnerHTML without proper content sanitization can expose users to XSS attacks. This is the same issue identified in previous reviews.

Consider implementing HTML sanitization:

+import DOMPurify from 'dompurify';

 <div
   className="prose prose-sm max-w-none"
   dangerouslySetInnerHTML={{
-    __html: campaign?.description ?? "",
+    __html: DOMPurify.sanitize(campaign?.description ?? ""),
   }}
src/entities/campaign/components/CampaignCarouselItem.tsx (1)

73-91: Critical security vulnerability: Unsanitized HTML rendering creates XSS risk.

The use of dangerouslySetInnerHTML with unsanitized campaign descriptions poses a serious XSS vulnerability. Based on previous feedback, this codebase traditionally uses Markdown for rich text formatting.

Consider these solutions:

  1. Recommended: Use a safe Markdown renderer instead of raw HTML:
-<div
-  className="prose prose-sm max-w-none overflow-hidden"
-  style={{
-    display: "-webkit-box",
-    WebkitLineClamp: 3,
-    WebkitBoxOrient: "vertical",
-    overflow: "hidden",
-    textOverflow: "ellipsis",
-  }}
-  dangerouslySetInnerHTML={{
-    __html: data.description ?? "",
-  }}
-  onClick={(event) => {
-    if (event.target instanceof HTMLAnchorElement) {
-      event.stopPropagation();
-    }
-  }}
-/>
+<div
+  className="prose prose-sm max-w-none overflow-hidden"
+  style={{
+    display: "-webkit-box",
+    WebkitLineClamp: 3,
+    WebkitBoxOrient: "vertical",
+    overflow: "hidden",
+    textOverflow: "ellipsis",
+  }}
+>
+  <ReactMarkdown>{data.description ?? ""}</ReactMarkdown>
+</div>
  1. Alternative: If HTML is required, sanitize it with DOMPurify:
+import DOMPurify from 'dompurify';

 dangerouslySetInnerHTML={{
-  __html: data.description ?? "",
+  __html: DOMPurify.sanitize(data.description ?? ""),
 }}
src/entities/campaign/components/CampaignCard.tsx (1)

60-80: Critical security vulnerability: Unsanitized HTML rendering creates XSS risk.

This is the same XSS vulnerability as in CampaignCarouselItem.tsx. The use of dangerouslySetInnerHTML without sanitization poses a serious security risk.

Apply the same fix as recommended for CampaignCarouselItem.tsx - either use a safe Markdown renderer or sanitize the HTML content with DOMPurify before rendering.

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

148-159: Critical security vulnerability: Unsanitized HTML rendering creates XSS risk.

This is the same XSS vulnerability present in the other campaign components. The use of dangerouslySetInnerHTML without sanitization poses a serious security risk.

Based on previous feedback indicating this codebase uses Markdown for rich text formatting, consider replacing this with a safe Markdown renderer instead of raw HTML rendering.

🧹 Nitpick comments (6)
src/entities/campaign/components/CampaignProgressBar.tsx (1)

22-22: Consider using consistent boolean type for isEnded

The boolean | string type for isEnded seems unusual. Consider using just boolean for better type safety and consistency.

-  isEnded: boolean | string;
+  isEnded: boolean;
src/entities/campaign/components/CampaignsList.tsx (1)

71-71: Document the campaign exclusion filter

The filter excluding on_chain_id !== 14 should be documented or use a named constant for clarity.

+// Exclude test/invalid campaign
+const EXCLUDED_CAMPAIGN_ID = 14;
+
 .filter((campaign) => campaign?.on_chain_id !== 14)
src/entities/campaign/components/CampaignCarouselItem.tsx (1)

6-6: Remove unused import.

The truncateHtml function is imported but never used in this component, as HTML rendering with dangerouslySetInnerHTML is used instead.

-import { truncate, truncateHtml } from "@/common/lib";
+import { truncate } from "@/common/lib";
src/entities/campaign/hooks/useCampaigns.ts (1)

17-22: LGTM! Hook implementation simplified effectively.

The refactoring to a single indexer.useCampaigns call with dynamic parameters based on the selected tab is much cleaner than the previous multiple hook approach.

Consider making the page size configurable or implementing proper pagination for better performance with large campaign datasets:

const { data: campaigns, isLoading: isCampaignsLoading } = indexer.useCampaigns({
  page: 1,
  page_size: pageSize ?? 300, // Make configurable
  ...(currentTab === CampaignTab.MY_CAMPAIGNS && { owner: viewer.accountId ?? NOOP_STRING }),
  ...(currentTab === CampaignTab.ACTIVE_CAMPAIGNS && { active: true }),
});
src/entities/campaign/components/CampaignCard.tsx (1)

6-6: Remove unused import.

The truncateHtml function is imported but never used, similar to the issue in CampaignCarouselItem.tsx.

-import { truncateHtml } from "@/common/lib";
src/entities/campaign/components/CampaignBanner.tsx (1)

58-68: Consider the impact of always enabling these hooks.

The hooks are now always enabled rather than conditionally enabled based on campaign state. This could result in unnecessary API calls when the campaign data isn't available yet.

Consider conditionally enabling based on campaign availability:

const { data: hasEscrowedDonations, isLoading: isHasEscrowedDonationsLoading } =
  campaignsContractHooks.useHasEscrowedDonationsToProcess({
    campaignId,
-   enabled: true, // Always enable the hook
+   enabled: !!campaign, // Enable only when campaign is loaded
  });
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9bad414 and 45e0701.

📒 Files selected for processing (14)
  • src/common/api/indexer/hooks.ts (2 hunks)
  • src/common/api/indexer/internal/client.generated.ts (9 hunks)
  • src/common/api/indexer/internal/config.ts (1 hunks)
  • src/common/lib/datetime.ts (1 hunks)
  • src/entities/campaign/components/CampaignBanner.tsx (9 hunks)
  • src/entities/campaign/components/CampaignCard.tsx (4 hunks)
  • src/entities/campaign/components/CampaignCarouselItem.tsx (4 hunks)
  • src/entities/campaign/components/CampaignProgressBar.tsx (5 hunks)
  • src/entities/campaign/components/CampaignSettings.tsx (9 hunks)
  • src/entities/campaign/components/CampaignsList.tsx (4 hunks)
  • src/entities/campaign/components/editor.tsx (10 hunks)
  • src/entities/campaign/hooks/useCampaigns.ts (1 hunks)
  • src/pages/campaigns.tsx (4 hunks)
  • src/pages/profile/[accountId]/campaigns.tsx (3 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/common/lib/datetime.ts
  • src/common/api/indexer/internal/config.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/pages/campaigns.tsx
  • src/entities/campaign/components/editor.tsx
🧰 Additional context used
🧠 Learnings (17)
📚 Learning: the `useaccountsocialprofile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.

Applied to files:

  • src/pages/profile/[accountId]/campaigns.tsx
  • src/entities/campaign/components/CampaignSettings.tsx
  • src/entities/campaign/components/CampaignBanner.tsx
  • src/common/api/indexer/internal/client.generated.ts
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: error handling for near contract calls should be implemented in the consuming code, not at the contr...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.

Applied to files:

  • src/pages/profile/[accountId]/campaigns.tsx
  • src/entities/campaign/components/CampaignSettings.tsx
  • src/entities/campaign/hooks/useCampaigns.ts
  • src/entities/campaign/components/CampaignBanner.tsx
  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: the `useaccountsocialprofile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.

Applied to files:

  • src/pages/profile/[accountId]/campaigns.tsx
  • src/entities/campaign/components/CampaignSettings.tsx
  • src/entities/campaign/components/CampaignBanner.tsx
  • src/common/api/indexer/internal/client.generated.ts
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: in src/features/donation/components/modal-confirmation-screen.tsx, the isfeebypassallowed flag is te...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.

Applied to files:

  • src/pages/profile/[accountId]/campaigns.tsx
  • src/entities/campaign/components/CampaignSettings.tsx
  • src/entities/campaign/components/CampaignsList.tsx
  • src/entities/campaign/hooks/useCampaigns.ts
  • src/entities/campaign/components/CampaignBanner.tsx
  • src/entities/campaign/components/CampaignProgressBar.tsx
  • src/common/api/indexer/internal/client.generated.ts
  • src/entities/campaign/components/CampaignCard.tsx
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: in the potlock codebase, using `{}` as a type parameter is acceptable for the `contractapi.call` met...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.

Applied to files:

  • src/common/api/indexer/hooks.ts
  • src/entities/campaign/components/CampaignSettings.tsx
  • src/entities/campaign/hooks/useCampaigns.ts
  • src/entities/campaign/components/CampaignBanner.tsx
  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: in the potlock codebase, using `{}` as a type parameter is acceptable for the `contractapi.view` met...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.

Applied to files:

  • src/common/api/indexer/hooks.ts
  • src/entities/campaign/components/CampaignSettings.tsx
  • src/entities/campaign/hooks/useCampaigns.ts
  • src/entities/campaign/components/CampaignBanner.tsx
  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: in src/pages/index.tsx, the donation count (total_donations_count) is intentionally displayed with a...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#424
File: src/pages/index.tsx:52-56
Timestamp: 2025-07-02T13:31:11.268Z
Learning: In src/pages/index.tsx, the donation count (total_donations_count) is intentionally displayed with a dollar sign prefix for UI consistency, even though it represents a count rather than a currency amount. This is the intended behavior.

Applied to files:

  • src/entities/campaign/components/CampaignSettings.tsx
  • src/entities/campaign/components/CampaignBanner.tsx
  • src/entities/campaign/components/CampaignCard.tsx
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: the `usewalletusersession` hook in this codebase returns a `walletusersession` object that is never ...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.

Applied to files:

  • src/entities/campaign/components/CampaignSettings.tsx
  • src/entities/campaign/hooks/useCampaigns.ts
  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: the transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and w...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
  • src/common/api/indexer/internal/client.generated.ts
  • src/entities/campaign/components/CampaignCard.tsx
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: in the `usewalletusersession` hook, when `issignedin` is true, it guarantees that `accountid` is ava...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: error handling for the `publishpayoutjustification` function is implemented at the consumer level in...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which manages loading state and provides success/error callbacks for UI feedback.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: error handling for the `publishpayoutjustification` function is implemented at the consumer level in...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides comprehensive error handling including loading state management, success/error callbacks, error logging, and proper cleanup.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: error handling for the `publishpayoutjustification` function is implemented at the consumer level in...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides `onPublishSuccess` and `onPublishError` callbacks for proper error handling in the UI layer.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: for api hooks using swr, the recommended approach for handling potentially undefined parameters is t...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: in the potlock project, `bypotid` type ensures that `potid` is a required property of type `accounti...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: the donation ft multicall function in src/features/donation/models/effects/ft.ts is designed to be e...
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.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: in the donation flow, message length is already restricted through schema validation with `message: ...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/models/effects/ft.ts:37-41
Timestamp: 2025-04-27T20:37:55.330Z
Learning: In the donation flow, message length is already restricted through schema validation with `message: string().max(DONATION_MAX_MESSAGE_LENGTH)` where `DONATION_MAX_MESSAGE_LENGTH = 100`. This validation prevents unbounded messages that could lead to disproportionate storage deposits in the `donationFtMulticall` function.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
🧬 Code Graph Analysis (4)
src/entities/campaign/components/CampaignSettings.tsx (5)
src/entities/_shared/token/hooks/fungible.ts (1)
  • useFungibleToken (35-197)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (120-120)
src/entities/_shared/token/components/icons.tsx (1)
  • TokenIcon (31-57)
src/entities/_shared/account/components/profile-images.tsx (1)
  • AccountProfilePicture (15-34)
src/common/lib/datetime.ts (1)
  • toTimestamp (113-119)
src/entities/campaign/hooks/useCampaigns.ts (2)
src/common/wallet/hooks.ts (1)
  • useWalletUserSession (14-95)
src/common/constants.ts (1)
  • NOOP_STRING (166-166)
src/entities/campaign/components/CampaignCard.tsx (4)
src/common/lib/datetime.ts (1)
  • toTimestamp (113-119)
src/entities/campaign/components/CampaignProgressBar.tsx (1)
  • CampaignProgressBar (25-239)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (120-120)
src/features/donation/components/user-entrypoints.tsx (1)
  • DonateToCampaign (85-107)
src/entities/campaign/components/CampaignCarouselItem.tsx (4)
src/common/lib/datetime.ts (1)
  • toTimestamp (113-119)
src/entities/_shared/account/components/AccountProfileLink.tsx (1)
  • AccountProfileLink (19-56)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (120-120)
src/features/donation/components/user-entrypoints.tsx (1)
  • DonateToCampaign (85-107)
🪛 Biome (2.1.2)
src/entities/campaign/components/CampaignSettings.tsx

[error] 173-173: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/entities/campaign/components/CampaignBanner.tsx

[error] 150-150: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/entities/campaign/components/CampaignCard.tsx

[error] 70-70: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/entities/campaign/components/CampaignCarouselItem.tsx

[error] 82-82: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (20.x)
  • GitHub Check: build (20.x)
🔇 Additional comments (39)
src/pages/profile/[accountId]/campaigns.tsx (4)

5-6: LGTM: Clean migration to indexer API

The import changes correctly switch from contract hooks to the new indexer API, and the UI components import is appropriately updated.


16-18: LGTM: Consistent API migration with proper parameter mapping

The migration from campaignsContractHooks.useOwnedCampaigns to indexer.useCampaigns is correct, and the parameter change from accountId to owner aligns with the indexer API schema.


30-33: Improved loading UI

The change from a full-page SplashScreen to a centered Spinner provides better UX consistency and is more appropriate for this loading state.


37-41: Correct adaptation to paginated data structure

The changes properly handle the new paginated response format by accessing campaigns?.results and using campaign.on_chain_id as the key, which aligns with the indexer data model.

src/common/api/indexer/hooks.ts (3)

8-8: LGTM: Proper staging configuration import

The addition of INDEXER_CLIENT_CONFIG_STAGING import supports the campaign-specific hooks that require staging environment access.


334-342: LGTM: Well-structured campaigns hook

The useCampaigns hook follows the established pattern in this file:

  • Proper parameter typing with defaults
  • Uses staging configuration for campaign data
  • Returns nested data field consistently

344-351: LGTM: Consistent campaign detail hook

The useCampaign hook is well-implemented:

  • Explicit SWR enablement is good practice
  • Uses staging configuration appropriately
  • Consistent return pattern with other hooks
src/entities/campaign/components/CampaignProgressBar.tsx (1)

110-120: LGTM: Simplified status text logic

The refactored statusText logic using isEnded is cleaner and more maintainable than the previous implementation.

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

1-3: LGTM: Correct imports for indexer migration

The import changes properly support the migration to the indexer API and add performance optimization with useMemo.


25-31: LGTM: Updated sorting for new date fields

The sorting logic correctly uses start_at instead of start_ms, aligning with the new indexer data schema.


48-77: Good performance optimization with memoized content

The memoized content rendering improves performance by preventing unnecessary re-renders. The loading and empty states are well-handled.

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

7-11: LGTM: Proper migration to indexer API

The imports correctly switch to the indexer API and add the necessary toTimestamp utility for date handling.


20-30: LGTM: Improved date formatting function

The formatTime function properly handles both string and number date inputs, making it more robust for the new data model.


64-70: LGTM: Consistent indexer hook usage

The migration to indexer.useCampaign and updated token access via campaign?.token?.account correctly aligns with the new data schema.


124-145: LGTM: Correct nested property access

The profile links properly access nested .id properties for both organizer and recipient, consistent with the indexer data model.


151-153: LGTM: Proper timestamp conversion

The edit condition correctly uses toTimestamp() for date comparison, ensuring consistent handling of the new date format.


196-197: LGTM: Updated time formatting with new date fields

The campaign duration display correctly uses start_at and end_at fields with the formatTime function.


236-239: LGTM: Valuable fee avoidance setting display

The addition of the "Fees Avoidance Allowed" setting provides users with important campaign configuration information.

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

17-23: LGTM! Data model migration implemented correctly.

The updates to use toTimestamp() for date conversion and on_chain_id for campaign identification are consistent with the broader migration to the indexer API data model.


41-48: LGTM! Nested data structure access is correct.

The updates to access data.recipient.id and data.owner.id properly reflect the new nested data structure from the indexer API.


62-70: LGTM! Progress bar props updated correctly.

The prop updates properly map to the new data structure:

  • data.token.account for token ID
  • data.net_raised_amount for amount
  • !data.is_active for ended state
  • toTimestamp() for date conversions

93-98: LGTM! Donation component props updated correctly.

The updates properly use the new data structure fields (data.token.account, data.on_chain_id) and simplify the disabled logic to use the new is_active flag.

src/entities/campaign/hooks/useCampaigns.ts (3)

1-11: LGTM! Imports simplified with indexer API migration.

The refactoring to use the unified indexer API and addition of the ACTIVE_CAMPAIGNS enum value properly supports the new functionality while simplifying the import structure.


24-44: LGTM! Button configuration updated correctly.

The addition of the "Active Campaigns" button and the simplified onClick handlers properly support the new tab functionality. The dependency array optimization is also well done.


46-52: LGTM! Return structure simplified and improved.

The simplified return structure with campaigns derived directly from campaigns?.results and a single loading flag from the indexer hook is much cleaner than the previous implementation.

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

17-55: LGTM! Data model updates implemented correctly.

The updates to use toTimestamp(), on_chain_id, and nested data.recipient.id are consistent with the broader API migration and properly reflect the new data structure.


82-92: LGTM! Progress bar props updated correctly.

The prop updates properly map to the new data structure, consistent with the changes in other campaign components.


94-99: LGTM! Donation component props updated correctly.

The updates to use new data structure fields and simplified is_active logic are consistent with the broader refactoring.

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

9-38: LGTM! API migration implemented correctly.

The switch from contract hooks to indexer.useCampaign and addition of the toTimestamp utility are consistent with the broader API migration pattern.


38-44: LGTM! Token data access updated correctly.

The updates to use campaign?.token.account and campaign?.net_raised_amount properly reflect the new data structure from the indexer API.


85-89: LGTM! Date conversion implemented correctly.

The use of toTimestamp() for start_at and end_at fields with appropriate fallback values is consistent with the broader date handling improvements.


124-134: LGTM! Nested data access with proper fallbacks.

The updates to access campaign?.recipient?.id and campaign?.owner?.id with empty string fallbacks properly handle the new nested data structure.


179-189: LGTM! Progress bar props updated correctly.

The updates to use new data structure fields, addition of the isEnded prop derived from !campaign?.is_active, and toTimestamp() for date conversions are all consistent with the broader refactoring.


192-289: LGTM! Conditional rendering logic improved.

The updates to use isProcessingHooksLoading for conditional rendering, updated field access patterns, and addition of a loading spinner for processing hooks improve both the code organization and user experience.

src/common/api/indexer/internal/client.generated.ts (5)

239-307: LGTM! Campaign parameter types are well-structured.

The new parameter types for campaign-related endpoints follow the established patterns and include appropriate filters for querying campaigns and donations.


627-628: LGTM! Consistent with existing monetary fields.

The minimum_deposit field follows the established pattern of using string type for monetary values in the Round interface.


1453-1667: LGTM! Comprehensive campaign data models.

The new Campaign-related interfaces are well-structured with:

  • Consistent use of string type for monetary values
  • Proper nullable/optional field annotations
  • Clear separation between Campaign, CampaignDonation, and CampaignContractConfig
  • Appropriate readonly modifiers for computed fields

2383-2384: Note the error type inconsistency.

Some campaign endpoints use AxiosError<unknown> while others use AxiosError<void>. Ensure this reflects the actual API error response types.

Also applies to: 2432-2433


1109-1116: LGTM! Interface updates maintain compatibility.

The interface modifications properly:

  • Standardize paginated response naming conventions
  • Add new campaign-specific response types
  • Enhance existing interfaces with optional fields to maintain backward compatibility

Also applies to: 1127-1152, 1193-1198, 1296-1335

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 01df50e and 71cf440.

📒 Files selected for processing (2)
  • src/common/api/indexer/internal/client.generated.ts (9 hunks)
  • src/entities/campaign/hooks/useCampaigns.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/entities/campaign/hooks/useCampaigns.ts
🧰 Additional context used
🧠 Learnings (10)
📚 Learning: the transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and w...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: in src/features/donation/components/modal-confirmation-screen.tsx, the isfeebypassallowed flag is te...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: in the potlock codebase, using `{}` as a type parameter is acceptable for the `contractapi.call` met...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: in the potlock codebase, using `{}` as a type parameter is acceptable for the `contractapi.view` met...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: error handling for near contract calls should be implemented in the consuming code, not at the contr...
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: the `useaccountsocialprofile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: the `useaccountsocialprofile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: in the potlock project, `bypotid` type ensures that `potid` is a required property of type `accounti...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#370
File: src/features/donation/models/effects/index.ts:60-63
Timestamp: 2025-05-13T03:39:29.454Z
Learning: In the PotLock project, `ByPotId` type ensures that `potId` is a required property of type `AccountId`. The codebase has TypeScript type checking in precommit hooks that prevents pushing code with type mismatches.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: the donation ft multicall function in src/features/donation/models/effects/ft.ts is designed to be e...
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.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
📚 Learning: in the donation flow, message length is already restricted through schema validation with `message: ...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#366
File: src/features/donation/models/effects/ft.ts:37-41
Timestamp: 2025-04-27T20:37:55.330Z
Learning: In the donation flow, message length is already restricted through schema validation with `message: string().max(DONATION_MAX_MESSAGE_LENGTH)` where `DONATION_MAX_MESSAGE_LENGTH = 100`. This validation prevents unbounded messages that could lead to disproportionate storage deposits in the `donationFtMulticall` function.

Applied to files:

  • src/common/api/indexer/internal/client.generated.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (20.x)
  • GitHub Check: build (20.x)
🔇 Additional comments (3)
src/common/api/indexer/internal/client.generated.ts (3)

638-639: LGTM!

The addition of minimum_deposit field follows the existing pattern of amount fields being strings and is properly documented.


1464-1678: LGTM!

The new campaign-related interfaces are well-structured and follow consistent patterns with existing API models. The comprehensive fee structure in CampaignDonation and the extensive properties in Campaign properly support the campaign functionality.


2332-2571: LGTM!

The new campaign API client functions and React SWR hooks are well-implemented:

  • Follow established patterns consistently
  • Include proper parameter validation (e.g., checking !!campaignId)
  • Have appropriate error handling and type definitions
  • Maintain consistency with existing API client structure

export const V1CampaignsRetrieveStatus = {
active: "active",
ended: "ended",
unfufilled: "unfufilled",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix typo in campaign status enum.

Line 265 contains a typo: "unfufilled" should be "unfulfilled".

- unfufilled: "unfufilled",
+ unfulfilled: "unfulfilled",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
unfufilled: "unfufilled",
unfulfilled: "unfulfilled",
🤖 Prompt for AI Agents
In src/common/api/indexer/internal/client.generated.ts at line 265, correct the
typo in the campaign status enum by changing "unfufilled" to "unfulfilled" to
ensure the status value is spelled correctly.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 71cf440 and 77eabf4.

📒 Files selected for processing (4)
  • src/common/blockchains/near-protocol/client.ts (4 hunks)
  • src/entities/campaign/components/CampaignsList.tsx (5 hunks)
  • src/entities/campaign/hooks/useCampaigns.ts (2 hunks)
  • src/entities/campaign/utils/constants.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/common/blockchains/near-protocol/client.ts
  • src/entities/campaign/hooks/useCampaigns.ts
  • src/entities/campaign/components/CampaignsList.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: in src/features/donation/components/modal-confirmation-screen.tsx, the isfeebypassallowed flag is te...
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.

Applied to files:

  • src/entities/campaign/utils/constants.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (20.x)
  • GitHub Check: build (20.x)
🔇 Additional comments (1)
src/entities/campaign/utils/constants.ts (1)

1-2: LGTM!

The import statement correctly brings in the required type for the new campaign status options constant.

Comment on lines +5 to +12
export const CAMPAIGN_STATUS_OPTIONS: { label: string; val: V1CampaignsRetrieveStatus | "all" }[] =
[
{ label: "All", val: "all" },
{ label: "Active", val: "active" },
{ label: "Ended", val: "ended" },
{ label: "Unfulfilled", val: "unfufilled" },
{ label: "Upcoming", val: "upcoming" },
];
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix spelling error in "unfufilled".

There's a typo in the "Unfulfilled" status option - it should be "unfulfilled" (with double 'l').

Apply this diff to fix the typo:

-    { label: "Unfulfilled", val: "unfufilled" },
+    { label: "Unfulfilled", val: "unfulfilled" },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const CAMPAIGN_STATUS_OPTIONS: { label: string; val: V1CampaignsRetrieveStatus | "all" }[] =
[
{ label: "All", val: "all" },
{ label: "Active", val: "active" },
{ label: "Ended", val: "ended" },
{ label: "Unfulfilled", val: "unfufilled" },
{ label: "Upcoming", val: "upcoming" },
];
export const CAMPAIGN_STATUS_OPTIONS: { label: string; val: V1CampaignsRetrieveStatus | "all" }[] =
[
{ label: "All", val: "all" },
{ label: "Active", val: "active" },
{ label: "Ended", val: "ended" },
{ label: "Unfulfilled", val: "unfulfilled" },
{ label: "Upcoming", val: "upcoming" },
];
🤖 Prompt for AI Agents
In src/entities/campaign/utils/constants.ts around lines 5 to 12, fix the
spelling error in the "Unfulfilled" status option by changing the value from
"unfufilled" to "unfulfilled" with double 'l'.

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

🔭 Outside diff range comments (3)
src/entities/campaign/components/CampaignCarouselItem.tsx (1)

43-56: OFFICIAL badge comparison uses object reference instead of IDs

Comparing objects with === here will almost always be false. Compare account IDs.

-              {data?.owner === data?.recipient && (
+              {data?.owner?.id === data?.recipient?.id && (
                 <div className="flex  items-center gap-1">
                   <BadgeIcon size={5} />
                   <span className="m-0 font-bold text-white">OFFICIAL</span>
                 </div>
               )}
src/entities/campaign/components/CampaignCard.tsx (1)

40-48: OFFICIAL badge check should compare account IDs

Object reference equality will fail here; compare owner.id and recipient.id.

-          {data?.owner === data?.recipient && (
+          {data?.owner?.id === data?.recipient?.id && (
             <div className="absolute right-2 top-2 flex  items-center gap-1">
               <BadgeIcon size={5} />
               <span className="m-0 font-bold text-white">OFFICIAL</span>
             </div>
           )}
src/entities/campaign/components/CampaignBanner.tsx (1)

138-144: OFFICIAL badge check should compare IDs, not objects

Use owner.id === recipient.id.

-              {campaign?.owner === campaign?.recipient && (
+              {campaign?.owner?.id === campaign?.recipient?.id && (
                 <div className="flex items-center gap-1">
                   <BadgeIcon size={5} />
                   <span className="m-0 font-bold">OFFICIAL</span>
                 </div>
               )}

Also applies to: 122-135

♻️ Duplicate comments (3)
src/entities/campaign/components/CampaignCarouselItem.tsx (1)

77-95: Sanitize HTML and fix invalid DOM nesting

  • Critical: Rendering user-provided HTML without sanitization is an XSS risk (Biome error at Line 86). Past reviews already flagged this; apply sanitization.
  • Structural: A div is nested inside a p (Line 76 wraps Line 77). This is invalid HTML and can break layout.

Apply both fixes:

+import DOMPurify from "dompurify";
@@
-          <p className="mt-4 text-start md:h-28">
-            <div
+          <div className="mt-4 text-start md:h-28">
+            <div
               className="prose prose-sm max-w-none overflow-hidden"
               style={{
                 display: "-webkit-box",
                 WebkitLineClamp: 3,
                 WebkitBoxOrient: "vertical",
                 overflow: "hidden",
                 textOverflow: "ellipsis",
               }}
               dangerouslySetInnerHTML={{
-                __html: data.description ?? "",
+                __html: DOMPurify.sanitize(data.description ?? ""),
               }}
               onClick={(event) => {
                 // Prevent navigation when clicking on links
                 if (event.target instanceof HTMLAnchorElement) {
                   event.stopPropagation();
                 }
               }}
             />
-          </p>
+          </div>

If SSR breaks with dompurify, use isomorphic-dompurify instead. Also consider a shared SafeHtml component to centralize sanitization.

Also applies to: 76-96, 4-4

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

62-81: Sanitize rendered HTML for campaign description

Rendering raw HTML via dangerouslySetInnerHTML without sanitization is unsafe (Biome error at Line 72). Prior reviews flagged this.

+import DOMPurify from "dompurify";
@@
           <div className="h-[100px]">
             <div
               className="prose prose-sm max-w-none overflow-hidden"
               style={{
                 display: "-webkit-box",
                 WebkitLineClamp: 3,
                 WebkitBoxOrient: "vertical",
                 overflow: "hidden",
                 textOverflow: "ellipsis",
               }}
               dangerouslySetInnerHTML={{
-                __html: data.description ?? "",
+                __html: DOMPurify.sanitize(data.description ?? ""),
               }}
               onClick={(event) => {
                 // Prevent navigation when clicking on links
                 if (event.target instanceof HTMLAnchorElement) {
                   event.stopPropagation();
                 }
               }}
             />
           </div>

Consider extracting a SafeHtml component to avoid repetition.

Also applies to: 6-6

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

148-159: Sanitize campaign.description before rendering

dangerouslySetInnerHTML uses raw data; sanitize to prevent XSS (Biome error at Line 150). This was flagged previously.

+import DOMPurify from "dompurify";
@@
-        <div
-          className="prose prose-sm max-w-none p-4"
-          dangerouslySetInnerHTML={{
-            __html: campaign?.description ?? "",
-          }}
-          onClick={(event) => {
-            // Prevent navigation when clicking on links
-            if (event.target instanceof HTMLAnchorElement) {
-              event.stopPropagation();
-            }
-          }}
-        />
+        <div
+          className="prose prose-sm max-w-none p-4"
+          dangerouslySetInnerHTML={{
+            __html: DOMPurify.sanitize(campaign?.description ?? ""),
+          }}
+          onClick={(event) => {
+            // Prevent navigation when clicking on links
+            if (event.target instanceof HTMLAnchorElement) {
+              event.stopPropagation();
+            }
+          }}
+        />

If SSR issues arise, use isomorphic-dompurify. Also consider a shared SafeHtml component.

Also applies to: 9-9, 13-13

🧹 Nitpick comments (3)
src/entities/campaign/components/CampaignBanner.tsx (3)

208-215: Fix typos and class mistakes

  • Typo: “reach” → “reached”.
  • ClassName: “h--12” should be “h-12”.
-                  <BadgeCheck className="h--12 w-12" />
+                  <BadgeCheck className="h-12 w-12" />
@@
-                    <p className="text-sm font-normal leading-6">
-                      The Minimum Target of the Campaign has been successfully reach and the
-                      Donations can be processed.
-                    </p>
+                    <p className="text-sm font-normal leading-6">
+                      The minimum target of the campaign has been successfully reached and the
+                      donations can be processed.
+                    </p>
@@
-                  <CircleAlert className="h--12 w-12" />
+                  <CircleAlert className="h-12 w-12" />

Also applies to: 239-245


85-90: Date handling is solid; minor consistency note

Using toTimestamp with nullish-coalescing for start/end dates is robust here and consistent across props.

For parity with Card/Carousel, consider also using the same numeric comparisons for isStarted/isEnded instead of string includes if you standardize that logic.

Also applies to: 179-189


148-159: Policy alignment: prefer Markdown over raw HTML (team decision)

Past reviews indicated a team choice to avoid HTML for rich text in favor of Markdown. If that decision still stands, replace dangerouslySetInnerHTML with a Markdown renderer (with sanitization) instead of HTML.

Would you like a follow-up patch replacing HTML rendering with a safe Markdown renderer (e.g., marked + dompurify or react-markdown with rehype-sanitize) across CampaignBanner/Card/Carousel for consistency?

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 77eabf4 and bf9cab6.

📒 Files selected for processing (4)
  • src/entities/campaign/components/CampaignBanner.tsx (9 hunks)
  • src/entities/campaign/components/CampaignCard.tsx (4 hunks)
  • src/entities/campaign/components/CampaignCarouselItem.tsx (4 hunks)
  • src/entities/campaign/components/CampaignProgressBar.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/entities/campaign/components/CampaignProgressBar.tsx
🧰 Additional context used
🧠 Learnings (14)
📚 Learning: 2025-06-02T18:44:53.590Z
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:83-88
Timestamp: 2025-06-02T18:44:53.590Z
Learning: In src/features/donation/components/modal-confirmation-screen.tsx, the isFeeBypassAllowed flag is temporarily hardcoded to true for urgent shipping, with a TODO comment indicating it should be replaced with campaign permission-based logic using campaign?.allow_fee_avoidance ?? false for campaign donations.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
  • src/entities/campaign/components/CampaignCard.tsx
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: 2025-07-02T13:31:11.268Z
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#424
File: src/pages/index.tsx:52-56
Timestamp: 2025-07-02T13:31:11.268Z
Learning: In src/pages/index.tsx, the donation count (total_donations_count) is intentionally displayed with a dollar sign prefix for UI consistency, even though it represents a count rather than a currency amount. This is the intended behavior.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
  • src/entities/campaign/components/CampaignCard.tsx
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: 2025-04-17T14:16:13.402Z
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#365
File: src/features/donation/models/effects/index.ts:155-174
Timestamp: 2025-04-17T14:16:13.402Z
Learning: The transaction outcome handling in src/features/donation/models/effects/index.ts is temporary and will be replaced with `nearRps.txStatus` in the future, so extensive refinements to the current implementation aren't necessary.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
  • src/entities/campaign/components/CampaignCard.tsx
📚 Learning: 2025-06-25T12:26:52.941Z
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined through the fallback chain: `nftMediaSrc ?? rawImageSrc ?? fallbackUrl`.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: 2025-06-25T12:26:52.941Z
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#418
File: src/layout/profile/components/team.tsx:21-37
Timestamp: 2025-06-25T12:26:52.941Z
Learning: The `useAccountSocialProfile` hook in `src/entities/_shared/account/hooks/social-profile.ts` returns `avatar` and `cover` objects where the `.url` property is guaranteed to be defined. The hook uses `useAccountSocialImageSrc` with fallback URLs (placeholder constants) to ensure these properties are never undefined.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
  • src/entities/campaign/components/CampaignCarouselItem.tsx
📚 Learning: 2025-06-02T18:39:56.068Z
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#400
File: src/features/donation/components/modal-confirmation-screen.tsx:174-196
Timestamp: 2025-06-02T18:39:56.068Z
Learning: The `useWalletUserSession` hook in this codebase returns a `WalletUserSession` object that is never `undefined`. Even when a user is not signed in, it returns an object with `isSignedIn: false` and the appropriate property values. The hook does not return `undefined` itself.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: 2025-05-24T01:18:16.844Z
Learnt from: akaia-shadowfox
PR: PotLock/potlock-nextjs-app#388
File: src/common/contracts/core/campaigns/client.ts:22-22
Timestamp: 2025-05-24T01:18:16.844Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.view` method in the campaigns contract client when the contract method doesn't accept arguments, despite the typical TypeScript recommendation to avoid empty object types.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: 2025-02-26T14:09:01.815Z
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#352
File: src/features/pot-configuration/hooks/forms.ts:134-137
Timestamp: 2025-02-26T14:09:01.815Z
Learning: In the `useWalletUserSession` hook, when `isSignedIn` is true, it guarantees that `accountId` is available, making additional checks for `accountId` redundant when used alongside `viewer.hasWalletReady && viewer.isSignedIn`.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: 2025-02-14T13:33:35.107Z
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#341
File: src/common/contracts/core/campaigns/client.ts:36-45
Timestamp: 2025-02-14T13:33:35.107Z
Learning: Error handling for NEAR contract calls should be implemented in the consuming code, not at the contract client level. The contract client layer (`src/common/contracts/core/campaigns/client.ts`) should remain focused on making the calls without error handling logic.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: 2025-03-12T14:17:45.439Z
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#357
File: src/common/contracts/core/campaigns/client.ts:52-52
Timestamp: 2025-03-12T14:17:45.439Z
Learning: In the PotLock codebase, using `{}` as a type parameter is acceptable for the `contractApi.call` method in the campaigns contract client, despite the typical TypeScript recommendation to avoid empty object types.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: 2025-02-16T08:29:40.102Z
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which manages loading state and provides success/error callbacks for UI feedback.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: 2025-02-16T08:29:40.102Z
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides comprehensive error handling including loading state management, success/error callbacks, error logging, and proper cleanup.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: 2025-02-16T08:29:40.102Z
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#342
File: src/features/proportional-funding/model/effects.ts:31-78
Timestamp: 2025-02-16T08:29:40.102Z
Learning: Error handling for the `publishPayoutJustification` function is implemented at the consumer level in the `usePFPayoutJustification` hook, which provides `onPublishSuccess` and `onPublishError` callbacks for proper error handling in the UI layer.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
📚 Learning: 2025-02-26T17:22:59.459Z
Learnt from: carina-akaia
PR: PotLock/potlock-nextjs-app#355
File: src/common/api/indexer/hooks.ts:184-185
Timestamp: 2025-02-26T17:22:59.459Z
Learning: For API hooks using SWR, the recommended approach for handling potentially undefined parameters is to utilize the `enabled` parameter in the SWR configuration rather than using fallback values like "noop". This prevents unnecessary API calls and follows modern React data fetching patterns.

Applied to files:

  • src/entities/campaign/components/CampaignBanner.tsx
🧬 Code Graph Analysis (2)
src/entities/campaign/components/CampaignCard.tsx (4)
src/common/lib/datetime.ts (1)
  • toTimestamp (113-119)
src/entities/campaign/components/CampaignProgressBar.tsx (1)
  • CampaignProgressBar (25-239)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (120-120)
src/features/donation/components/user-entrypoints.tsx (1)
  • DonateToCampaign (85-107)
src/entities/campaign/components/CampaignCarouselItem.tsx (4)
src/common/lib/datetime.ts (1)
  • toTimestamp (113-119)
src/entities/_shared/account/components/AccountProfileLink.tsx (1)
  • AccountProfileLink (19-56)
src/common/constants.ts (1)
  • NATIVE_TOKEN_ID (120-120)
src/features/donation/components/user-entrypoints.tsx (1)
  • DonateToCampaign (85-107)
🪛 Biome (2.1.2)
src/entities/campaign/components/CampaignBanner.tsx

[error] 150-150: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/entities/campaign/components/CampaignCard.tsx

[error] 72-72: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

src/entities/campaign/components/CampaignCarouselItem.tsx

[error] 86-86: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

🪛 ast-grep (0.38.6)
src/entities/campaign/components/CampaignBanner.tsx

[warning] 149-149: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

src/entities/campaign/components/CampaignCard.tsx

[warning] 71-71: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

src/entities/campaign/components/CampaignCarouselItem.tsx

[warning] 85-85: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html

(react-unsafe-html-injection)

🔇 Additional comments (4)
src/entities/campaign/components/CampaignCarouselItem.tsx (2)

97-102: Donation button logic looks good

Using cachedTokenId from data.token.account and disabling based on is_active aligns with other components.


73-74: Unnecessary startDate fallback – ignore this suggestion

The Campaign type from our indexer client defines start_at: string (required), so toTimestamp(data.start_at) will always receive a valid string and never undefined. No additional ?? 0 fallback is needed here.

The numeric‐comparison refactor is purely stylistic—and existing getTimePassed().includes("-") logic is already used consistently elsewhere—so you can disregard the proposed change.

Likely an incorrect or invalid review comment.

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

96-101: Donation button change is consistent

Using on_chain_id and disabling on !data.is_active matches other components.

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

266-272: Ignore outdated disabled‐logic refactor suggestion

The proposed change to use disabled={!campaign?.is_active} doesn’t apply here:

  • Neither CampaignCard nor CampaignCarouselItem pass a disabled prop to <DonateToCampaign>, so there’s no existing “elsewhere” predicate to align with.
  • There is no campaign.is_active field in the current campaign model.
  • If you do want a unified disable rule, it should be implemented on the <DonateToCampaign> component itself (or via a shared utility) rather than swapping in a nonexistent property in only one place.

Likely an incorrect or invalid review comment.

Comment on lines 84 to 94
<CampaignProgressBar
tokenId={data.ft_id ?? NATIVE_TOKEN_ID}
startDate={Number(data?.start_ms)}
amount={data?.total_raised_amount ?? `${0}`}
tokenId={data?.token?.account ?? NATIVE_TOKEN_ID}
startDate={toTimestamp(data?.start_at)}
amount={data?.net_raised_amount ?? `${0}`}
minAmount={data?.min_amount ?? `${0}`}
target={data?.target_amount ?? `${0}`}
isStarted={isStarted}
isEnded={isEnded}
isEscrowBalanceEmpty={data?.escrow_balance === "0"}
endDate={Number(data?.end_ms)}
endDate={toTimestamp(data?.end_at ?? 0)}
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Align startDate handling with endDate: add fallback

To avoid passing undefined to toTimestamp, mirror the endDate pattern.

-          <CampaignProgressBar
+          <CampaignProgressBar
             tokenId={data?.token?.account ?? NATIVE_TOKEN_ID}
-            startDate={toTimestamp(data?.start_at)}
+            startDate={toTimestamp(data?.start_at ?? 0)}
             amount={data?.net_raised_amount ?? `${0}`}
             minAmount={data?.min_amount ?? `${0}`}
             target={data?.target_amount ?? `${0}`}
             isStarted={isStarted}
             isEnded={isEnded}
             isEscrowBalanceEmpty={data?.escrow_balance === "0"}
             endDate={toTimestamp(data?.end_at ?? 0)}
           />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<CampaignProgressBar
tokenId={data.ft_id ?? NATIVE_TOKEN_ID}
startDate={Number(data?.start_ms)}
amount={data?.total_raised_amount ?? `${0}`}
tokenId={data?.token?.account ?? NATIVE_TOKEN_ID}
startDate={toTimestamp(data?.start_at)}
amount={data?.net_raised_amount ?? `${0}`}
minAmount={data?.min_amount ?? `${0}`}
target={data?.target_amount ?? `${0}`}
isStarted={isStarted}
isEnded={isEnded}
isEscrowBalanceEmpty={data?.escrow_balance === "0"}
endDate={Number(data?.end_ms)}
endDate={toTimestamp(data?.end_at ?? 0)}
/>
<CampaignProgressBar
tokenId={data?.token?.account ?? NATIVE_TOKEN_ID}
startDate={toTimestamp(data?.start_at ?? 0)}
amount={data?.net_raised_amount ?? `${0}`}
minAmount={data?.min_amount ?? `${0}`}
target={data?.target_amount ?? `${0}`}
isStarted={isStarted}
isEnded={isEnded}
isEscrowBalanceEmpty={data?.escrow_balance === "0"}
endDate={toTimestamp(data?.end_at ?? 0)}
/>
🤖 Prompt for AI Agents
In src/entities/campaign/components/CampaignCard.tsx around lines 84 to 94, the
startDate prop is passed as toTimestamp(data?.start_at) without a fallback,
which can cause undefined to be passed. To fix this, add a fallback value
similar to endDate by changing startDate to toTimestamp(data?.start_at ?? 0) to
ensure a defined value is always passed.

Added set current button and fixed validation issues on create campaign page
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.

2 participants