Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedToo many files! This PR contains 230 files, which is 80 over the limit of 150. You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughSwitches 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
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)
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 ContractModalThe commented-out
dispatchblock insrc/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–66Suggested 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:
- Implementing the missing change handler functionality
- Removing the commented code if it's no longer needed
- 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,
unknownis more appropriate thanstring | 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 AccountCardThe
<p>wrapper insrc/entities/list/components/AccountCard.tsxalways renders (withclassName="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 whenprofile.descriptionis 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
useNonFungibleTokenoruseNftTokento distinguish it from the fungible tokenuseTokenhook that was renamed touseFungibleTokenelsewhere 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-formand provides excellent UX with prefixed input extensions showing the URL structure. The use ofFieldInputExtensionfor 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:
- The leading slash removal logic could be more explicit
- The fallback to the original URL when no match is found is good
- 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 insertionUsing
window.promptfor 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 optimizedThe
wouldExceedLimitfunction 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 sectionsLarge 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() behaviorUsing
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
⛔ Files ignored due to path filters (1)
yarn.lockis 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
useAccountSocialProfileimport to the more specific@/entities/_shared/accountpath 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
AccountCategoryandAccountListRegistrationStatusVariantimports 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
useTokentouseFungibleTokenaligns with the broader codebase refactoring to standardize fungible token data fetching.
34-37: LGTM! Hook usage correctly updated to new API.The
useFungibleTokenhook is properly configured with the required parameters:
balanceCheckAccountIdfor balance queriestokenIdfor the staking tokenThe returned data structure is correctly accessed as
stakingToken?.balanceUsdin 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
ProfileSetupDaoProgresstoProfileConfigurationDaoProgressmaintains 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 additionThe 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 hookThe import update aligns with the codebase-wide migration to standardized fungible token hooks.
37-40: LGTM - Hook call migration maintains compatibilityThe
useFungibleTokenhook call maintains the same parameter structure as the previoususeTokencall. 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 moduleThe import update consolidates token-related functionality under the dedicated token module.
66-66: LGTM - Hook migration with compatible parametersThe simplified hook call leverages the default values (
enabled: true,live: false) ofuseFungibleToken, maintaining the same behavior as the previous implementation.src/features/donation/hooks/form.ts (2)
16-16: LGTM - Migration to specialized token hookThe import update moves to the dedicated fungible token module for better organization.
134-137: LGTM - Enhanced hook usage with balance checkingThe migration to
useFungibleTokennow includesbalanceCheckAccountIdparameter, 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 importsBoth
useFungibleTokenandTokenIconare now imported from the dedicated token module, improving code organization and consistency across the codebase.
34-34: LGTM - Straightforward hook migrationThe
useFungibleTokencall 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
useTokentouseFungibleTokenaligns with the systematic refactoring across the codebase to consolidate token-related hooks.
26-33: Hook usage updated correctly.The
useFungibleTokenhook is being used appropriately with the correct parameters. The hook signature matches the usage pattern and maintains the same functionality as the previoususeTokenhook.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
useTokentouseFungibleTokenis consistent with the systematic refactoring across the codebase.
34-34: Hook usage updated correctly for native token.The
useFungibleTokenhook is being used appropriately withNATIVE_TOKEN_IDto 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 thetruncatefunction always receives a string parameter, preventing potential runtime errors whendataForList?.nameis 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 refactorThe migration from
useTokentouseFungibleTokenaligns 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 improvementAdding nullish coalescing with empty string fallbacks ensures
truncatealways 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 importsThe migration to
useFungibleTokenand 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 modularizationMoving account-related imports to the dedicated
@/entities/_shared/accountmodule 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
useTokentouseFungibleTokenis consistent with the broader refactor, and the addition oflive: trueis 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
useTokentouseFungibleTokenwith 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
useTokentouseFungibleTokenwith 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
avatarSrctoavatar.urlaligns with the profile image standardization effort. According to the retrieved learnings, theuseAccountSocialProfilehook guarantees that theavatar.urlproperty 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
avatarSrctoavataraligns with theuseAccountSocialProfilehook 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.urlcorrectly accesses the new object structuresrc/entities/pot/components/PotDonationStats.tsx (2)
9-9: LGTM: Updated to use standardized fungible token hook.The import change from
useTokentouseFungibleTokenaligns with the codebase-wide standardization of token data fetching.
27-27: LGTM: Consistent hook usage updates.Both
useFungibleTokencalls maintain the same parameters and functionality as the previoususeTokencalls, 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
useTokentouseFungibleToken.
24-27: LGTM: Deprecated comment and hook usage properly updated.Good maintenance:
- The deprecated comment correctly references
useFungibleTokeninstead of the olduseToken- 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/datato../hooks/fungiblereflects the module reorganization, and the hook renames (useToken→useFungibleToken,useTokenAllowlist→useFungibleTokenAllowlist) align with the codebase-wide standardization.
29-32: LGTM: Hook calls updated consistently.Both
useFungibleTokenanduseFungibleTokenAllowlistcalls 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
useTokentouseFungibleTokenis 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
useFungibleTokenhook call maintains the same parameters as the previoususeTokenimplementation, ensuring functional compatibility.src/common/contracts/tokens/fungible/client.ts (3)
1-1: Good refactor to namespace imports.Using namespace imports for
nearProtocolClientimproves code organization and makes the relationship between related exports clearer.
13-18: Client call updated correctly.The update to use
nearProtocolClient.naxiosInstanceis 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 !== 404prevents 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:
- More specific import path for
AccountListItemfrom the account submodule- Migration to
useFungibleTokenfor better semantic clarity
28-31: Token hook migration implemented correctly.The
useFungibleTokenhook call maintains the same parameter structure as the previoususeTokenimplementation, ensuring backward compatibility.src/entities/campaign/hooks/forms.ts (2)
15-15: Token hook import migration completed.The import change to
useFungibleTokenfrom the more specific@/entities/_shared/tokenpath completes the systematic refactor across the codebase.
67-69: Hook usage updated consistently.The
useFungibleTokenhook maintains the same parameter structure (tokenIdand optionalbalanceCheckAccountId), 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
useTokentouseFungibleTokenaligns 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
Cartfeature enum member is well-documented and follows the existing pattern for feature flags.
51-53: LGTM! Useful type alias for contract operations.The
ByContractAccountIdtype 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
LiveUpdateParamstype 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
FromSchemautility. 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
handleFileBufferChangefollows 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
cnutility to combine default styles with optional custom styles is the correct approach. The memoization dependency array properly includesclassNames?.inputExtensionsince 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_REGISTRYanddonationContractHooksimports 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.isEnabledflag, allowing for controlled feature rollout.
128-140: LGTM! Good loading state UX pattern.The conditional rendering with
Skeletonduring 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
otherproperty 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
useFungibleTokenAllowlisthooks, 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
disabledtoenabledparameter 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 whenenabledisfalse.
21-26: Inline SWR configuration is appropriate.The inline SWR configuration replacing
CONTRACT_SWR_CONFIGmaintains 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 listBefore 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 previouspost‐based call returned.- Performance (latency and payload size) is at least as good as before.
–– No other
nearSocialClient.keysusages 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
TextAreaFieldand addRichTextEditorto support the rich text editing functionality.
18-18: Consistent with token hook refactoring.The change from
useTokentouseFungibleTokenaligns 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
RichTextEditorintegration correctly:
- Binds to the form's description value
- Uses
setValuewith 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
onValueChangeto 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, andonValueChangeto 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-2from 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-input→border-neutral-300(more specific color)rounded-lg→rounded-md(slightly less rounded)p-1→p-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
liveparameter to control SWR revalidation behavior. The conditional SWR configuration properly disables all revalidation triggers whenlive=false, allowing for static data after initial fetch, while preserving SWR's default behavior whenlive=true.src/common/api/intear-token-indexer/hooks.ts (1)
9-37: LGTM! Consistent refactoring to standardize hook parameters.The refactoring from
disabledtoenabledparameter makes the API more intuitive, and the addition of theliveparameter 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-elementsaligns 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
truncatefunction correctly handles null/undefined values using optional chaining and provides appropriate fallback behavior.
27-33: LGTM! Simple and effective URL validation.The
isValidHttpUrlfunction provides a clean approach to URL validation using the nativeURLconstructor 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
useAccountSocialProfilehook which now returnsavatarandcoverobjects with guaranteed.urlproperties. This aligns with the enhanced image resolution usinguseAccountSocialImageSrc.Also applies to: 24-29
39-40: Good practice: Extracting reusable CSS class constant.The
contentClassNameextraction improves code maintainability and reduces duplication.
47-47: LGTM: Cover image handling updated consistently.The changes properly use the new
cover.urlproperty 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
useTokentouseFungibleTokenaligns 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
cnutility 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
liveparameter provides flexibility for real-time data updates, and the integration with the updateduseSocialProfilehook 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
useAccountSocialImageSrcprovides enhanced image handling with NFT support and guaranteed fallback URLs. The new return structure withavatarandcoverobjects (each with.urlproperty) 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
undefinedon 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
DonateToAccountButtonPropsto includeButtonPropsproperties 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/ProfileSetupInputstoProfileConfigurationMode/ProfileConfigurationInputsis 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
Labelcomponent with the standardizedFormLabelfrom 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
divandFormLabelmakes 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
disabledwithenabled(defaulting to true) and addition of theliveparameter provides better control over data fetching behavior. The conditional SWR configuration correctly disables all revalidation triggers whenliveis false, which is perfect for static data scenarios.
19-19: Proper conditional fetching implementation.The SWR key functions correctly return
nullwhenenabledis 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
enabledflag to conditionally fetch NFT data and provides fallback values. The usage ofNOOP_STRINGfollows 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 fornftParamsThe existing expression
data !== undefined && typeof data !== "string" && "nft" in data ? (data.nft ?? null) : nullalready handles both
undefinedandnullcases fordata.nft. Sincedata.nftis strongly typed as an object when present (perImage.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
stripLinktreefunction uses a clean functional approach withevolveto 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_LENGTHconstant improves maintainability and consistency.
31-31: LGTM! Schema rename reflects feature evolution.The rename from
profileSetupSchematoprofileConfigurationSchemaaligns with the broader refactoring mentioned in the AI summary.
47-50: LGTM! Well-constrained new field addition.The new
publicGoodReasonfield has appropriate validation constraints (20-500 characters) and is properly marked as optional.
43-43: profileImage Optionality VerifiedAll usages of
profileImagegracefully handle an undefined value:
- In
normalization.ts, it’s conditionally spread only when present.- In
hooks/forms.ts, initial values may beundefinedand updates usesetValueappropriately.- In
image-upload.tsx, rendering is wrapped in a truthy check before usingprofileImage.- In
editor.tsx, it falls back toavatar.urlvia 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
NonFungibleTokenMetadatainterface 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
NonFungibleTokenContractMetadatainterface 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
NonFungibleTokenandNonFungibleTokenLookupParamstypes 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
CustomTextFormtoTextAreaFieldaligns 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
CustomTextFormwithTextAreaFieldis good, and the addition ofrequiredandmaxLength={250}props improves form validation. TheclassNameplacement on the field component is appropriate.
14-14: CustomInput export verified
TheCustomInputcomponent is exported insrc/features/profile-configuration/components/editor-elements.tsxat line 51, so the import path inAddFundingSourceModal.tsxis correct.src/features/profile-configuration/components/contracts-section.tsx (3)
1-1: LGTM - Added required imports.The addition of
CSSPropertiesandcnutility imports are necessary for the new inlineLabelcomponent implementation.Also applies to: 17-17
23-38: LGTM - Well-implemented inline component.The new
Labelcomponent is a clean, functional implementation that properly uses thecnutility 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_LENGTHconstant 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
Pickto extract relevant fields fromProfileConfigurationInputs, 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
useCallbackhooks.
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
Pottype.
26-27: LGTM - Consistent with architectural migration.The switch from
useAccount(indexer) touseAccountSocialProfileand fromuseTokentouseFungibleTokenaligns 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
isRecipientProfileLoadingthroughout 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
hideZeroBalanceOptionstohideBalancesaligns 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
LiveUpdateParamstype aligns with the broader refactoring pattern across the codebase.
16-16: LGTM!The hook rename from
useTokenAllowlisttouseFungibleTokenAllowlistand parameter type change toConditionalActivationimprove clarity and consistency.
35-40: LGTM!The hook rename to
useFungibleTokenand addition of theliveparameter fromLiveUpdateParamsare well-implemented. The default value offalseforliveensures backward compatibility.
49-49: Consistent implementation of the enabled patternAll the
enabledconditions have been correctly updated to use the new pattern, properly combining theenabledparameter with token ID validity checks and theliveflag 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 featuresThe 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
ConditionalActivationwithenabledparameter aligns with the codebase-wide pattern.
39-64: Well-implemented live update supportThe
useViewAccounthook correctly implements:
- The
enabledpattern withIS_CLIENTcheck 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
ProfileSetupFormParamstoProfileFormParamsand hook rename touseProfileFormalign with the domain terminology update.
35-35: Good addition of live updatesAdding
live: truetouseAccountSocialProfileenables real-time social profile updates, improving user experience.
41-42: NFT-aware image handlingThe conditional logic
avatar.isNft ? undefined : avatar.urlproperly 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 fieldsAll 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 updatesUsing
useAccountSocialProfilewithlive: trueensures the avatar and cover images stay synchronized with the latest data.
159-166: Improved form field consistencyThe 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.
| // 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 }) | ||
| */ |
There was a problem hiding this comment.
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.
| <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(); | ||
| } | ||
| }} | ||
| /> |
There was a problem hiding this comment.
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.
| <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(); | ||
| } | ||
| }} | ||
| /> |
There was a problem hiding this comment.
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:
- 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();
}
}}
/>- 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.
| <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.
| 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); | ||
| }; |
There was a problem hiding this comment.
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.
| 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.
| <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> |
There was a problem hiding this comment.
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"; |
There was a problem hiding this comment.
💡 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.tsxLength of output: 1206
🏁 Script executed:
#!/bin/bash
# Display CampaignCard.tsx around the HTML rendering block
sed -n '1,200p' src/entities/campaign/components/CampaignCard.tsxLength 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.descriptionbefore passing to__html. - Remove the unused
truncateHtmlimport 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.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 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
liveprop 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
liveprop 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-nonetoleading-[1.1]provides slightly better line spacing and improves readability of the heading text.
There was a problem hiding this comment.
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 behaviorThe
stripLinktreeutility 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
useEffectis 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 functionextractRepositoryPath.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
handleChangefunction 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
📒 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 delegationThe component now correctly delegates delete operations to the parent component through the
onDeleteClickprop, following the established pattern for edit operations.Also applies to: 108-108, 143-143
119-119: Good improvement on key uniquenessUsing a composite key with the index prevents React reconciliation issues when there are duplicate investor names.
139-139: Correct button type specificationAdding
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 patternThe 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 initializationThe 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 handlersThe 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 inInstead 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 implementationThe 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 uniquenessIncluding 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 validationThe 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 handlersAll 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 useEnhancedFormThe migration from
useFormtouseEnhancedFormis 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 sectionThe
ProfileConfigurationRepositoriesSectionreturningnullwhenvaluesis empty does not block adding repositories— the “Add Repository” button is rendered unconditionally in the parent (src/features/profile-configuration/components/editor.tsxaround 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.
| {values.map((repo, index) => ( | ||
| <Repo | ||
| key={`${repo}-${index}`} | ||
| repo={repo} | ||
| index={index} | ||
| onChangeHandler={handleChange} | ||
| onRemoveHandler={handleRemove} | ||
| /> | ||
| ))} |
There was a problem hiding this comment.
🛠️ 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.
| {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.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (6)
src/entities/_shared/account/components/AccountProfileLink.tsx (2)
6-6: Remove unused import.The
truncatefunction 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
titleattribute 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
/6creates 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:
- Remove the console.log statement for production
- 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_campaignfunction 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:
- 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)!, }); };
- 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: { /* ... */ }, },
- 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
📒 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_nameandproject_descriptionfields 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_nameandproject_descriptionfollows 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.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 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.
| 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)!, | ||
| }); |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify deposit calculation and consider configurable defaults.
The social profile creation logic is solid, but consider these improvements:
- The 0.1 NEAR buffer in deposit calculation appears arbitrary - ensure this is sufficient for gas costs.
- Empty categories array as default might not be ideal for discoverability.
- 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 tsLength 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.1NEAR 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_SRCconfigurable (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.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis 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.
| 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"], | ||
| }, | ||
| }), |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Update metadata URL and icons to reflect Potlock app resources.
The Unity Wallet configuration uses placeholder values that should be updated:
- The
urlcurrently points to the wallet-selector library repository instead of the actual Potlock app - The
iconsarray 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.
| 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.
There was a problem hiding this comment.
Actionable comments posted: 0
🔭 Outside diff range comments (1)
src/entities/campaign/components/CampaignProgressBar.tsx (1)
185-196: Fix dependency array in titleContent useMemoThe dependency array is missing
isEndedbut the function references it. Also,isTimeUpis 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 sanitizationUsing
dangerouslySetInnerHTMLwithout 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
dangerouslySetInnerHTMLwith unsanitized campaign descriptions poses a serious XSS vulnerability. Based on previous feedback, this codebase traditionally uses Markdown for rich text formatting.Consider these solutions:
- 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>
- 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 ofdangerouslySetInnerHTMLwithout 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
dangerouslySetInnerHTMLwithout 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 forisEndedThe
boolean | stringtype forisEndedseems unusual. Consider using justbooleanfor better type safety and consistency.- isEnded: boolean | string; + isEnded: boolean;src/entities/campaign/components/CampaignsList.tsx (1)
71-71: Document the campaign exclusion filterThe filter excluding
on_chain_id !== 14should 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
truncateHtmlfunction is imported but never used in this component, as HTML rendering withdangerouslySetInnerHTMLis 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.useCampaignscall 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
truncateHtmlfunction is imported but never used, similar to the issue inCampaignCarouselItem.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
📒 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.tsxsrc/entities/campaign/components/CampaignSettings.tsxsrc/entities/campaign/components/CampaignBanner.tsxsrc/common/api/indexer/internal/client.generated.tssrc/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.tsxsrc/entities/campaign/components/CampaignSettings.tsxsrc/entities/campaign/hooks/useCampaigns.tssrc/entities/campaign/components/CampaignBanner.tsxsrc/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.tsxsrc/entities/campaign/components/CampaignSettings.tsxsrc/entities/campaign/components/CampaignBanner.tsxsrc/common/api/indexer/internal/client.generated.tssrc/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.tsxsrc/entities/campaign/components/CampaignSettings.tsxsrc/entities/campaign/components/CampaignsList.tsxsrc/entities/campaign/hooks/useCampaigns.tssrc/entities/campaign/components/CampaignBanner.tsxsrc/entities/campaign/components/CampaignProgressBar.tsxsrc/common/api/indexer/internal/client.generated.tssrc/entities/campaign/components/CampaignCard.tsxsrc/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.tssrc/entities/campaign/components/CampaignSettings.tsxsrc/entities/campaign/hooks/useCampaigns.tssrc/entities/campaign/components/CampaignBanner.tsxsrc/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.tssrc/entities/campaign/components/CampaignSettings.tsxsrc/entities/campaign/hooks/useCampaigns.tssrc/entities/campaign/components/CampaignBanner.tsxsrc/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.tsxsrc/entities/campaign/components/CampaignBanner.tsxsrc/entities/campaign/components/CampaignCard.tsxsrc/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.tsxsrc/entities/campaign/hooks/useCampaigns.tssrc/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.tsxsrc/common/api/indexer/internal/client.generated.tssrc/entities/campaign/components/CampaignCard.tsxsrc/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 APIThe 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 mappingThe migration from
campaignsContractHooks.useOwnedCampaignstoindexer.useCampaignsis correct, and the parameter change fromaccountIdtoowneraligns with the indexer API schema.
30-33: Improved loading UIThe change from a full-page
SplashScreento a centeredSpinnerprovides better UX consistency and is more appropriate for this loading state.
37-41: Correct adaptation to paginated data structureThe changes properly handle the new paginated response format by accessing
campaigns?.resultsand usingcampaign.on_chain_idas the key, which aligns with the indexer data model.src/common/api/indexer/hooks.ts (3)
8-8: LGTM: Proper staging configuration importThe addition of
INDEXER_CLIENT_CONFIG_STAGINGimport supports the campaign-specific hooks that require staging environment access.
334-342: LGTM: Well-structured campaigns hookThe
useCampaignshook follows the established pattern in this file:
- Proper parameter typing with defaults
- Uses staging configuration for campaign data
- Returns nested
datafield consistently
344-351: LGTM: Consistent campaign detail hookThe
useCampaignhook 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 logicThe refactored
statusTextlogic usingisEndedis cleaner and more maintainable than the previous implementation.src/entities/campaign/components/CampaignsList.tsx (3)
1-3: LGTM: Correct imports for indexer migrationThe import changes properly support the migration to the indexer API and add performance optimization with
useMemo.
25-31: LGTM: Updated sorting for new date fieldsThe sorting logic correctly uses
start_atinstead ofstart_ms, aligning with the new indexer data schema.
48-77: Good performance optimization with memoized contentThe 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 APIThe imports correctly switch to the indexer API and add the necessary
toTimestamputility for date handling.
20-30: LGTM: Improved date formatting functionThe
formatTimefunction properly handles both string and number date inputs, making it more robust for the new data model.
64-70: LGTM: Consistent indexer hook usageThe migration to
indexer.useCampaignand updated token access viacampaign?.token?.accountcorrectly aligns with the new data schema.
124-145: LGTM: Correct nested property accessThe profile links properly access nested
.idproperties for both organizer and recipient, consistent with the indexer data model.
151-153: LGTM: Proper timestamp conversionThe 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 fieldsThe campaign duration display correctly uses
start_atandend_atfields with theformatTimefunction.
236-239: LGTM: Valuable fee avoidance setting displayThe 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 andon_chain_idfor 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.idanddata.owner.idproperly 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.accountfor token IDdata.net_raised_amountfor amount!data.is_activefor ended statetoTimestamp()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 newis_activeflag.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_CAMPAIGNSenum 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?.resultsand 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 nesteddata.recipient.idare 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_activelogic 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.useCampaignand addition of thetoTimestamputility are consistent with the broader API migration pattern.
38-44: LGTM! Token data access updated correctly.The updates to use
campaign?.token.accountandcampaign?.net_raised_amountproperly reflect the new data structure from the indexer API.
85-89: LGTM! Date conversion implemented correctly.The use of
toTimestamp()forstart_atandend_atfields 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?.idandcampaign?.owner?.idwith 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
isEndedprop derived from!campaign?.is_active, andtoTimestamp()for date conversions are all consistent with the broader refactoring.
192-289: LGTM! Conditional rendering logic improved.The updates to use
isProcessingHooksLoadingfor 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_depositfield 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 useAxiosError<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
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 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_depositfield 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
CampaignDonationand the extensive properties inCampaignproperly 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", |
There was a problem hiding this comment.
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.
| 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.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 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.
| 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" }, | ||
| ]; |
There was a problem hiding this comment.
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.
| 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'.
There was a problem hiding this comment.
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 IDsComparing 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 IDsObject 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 objectsUse 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 descriptionRendering 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 renderingdangerouslySetInnerHTML 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 noteUsing 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
📒 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.tsxsrc/entities/campaign/components/CampaignCard.tsxsrc/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.tsxsrc/entities/campaign/components/CampaignCard.tsxsrc/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.tsxsrc/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.tsxsrc/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.tsxsrc/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 goodUsing cachedTokenId from data.token.account and disabling based on is_active aligns with other components.
73-74: Unnecessary startDate fallback – ignore this suggestionThe
Campaigntype from our indexer client definesstart_at: string(required), sotoTimestamp(data.start_at)will always receive a valid string and neverundefined. No additional?? 0fallback 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 consistentUsing 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 suggestionThe proposed change to use
disabled={!campaign?.is_active}doesn’t apply here:
- Neither CampaignCard nor CampaignCarouselItem pass a
disabledprop to<DonateToCampaign>, so there’s no existing “elsewhere” predicate to align with.- There is no
campaign.is_activefield 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.
| <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)} | ||
| /> |
There was a problem hiding this comment.
🛠️ 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.
| <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.
Feature/sync accounts lists
Staging to prod
Feature/sync pots
Added Ramadan to Featured Campaigns
Staging to prod
Staging to prod
fixed cross chain minimum account
Staging to prod
…und-unescrow Feature/campaign sync delete refund unescrow
Added set current button and fixed validation issues on create campaign page
Summary by CodeRabbit
New Features
Enhancements
Bug Fixes
Chores