-
Notifications
You must be signed in to change notification settings - Fork 198
feat: explore page portals tags and category page #10220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughWalkthroughThis change introduces category and tag-based filtering to the Explore page, including new routes for category/tag navigation, a tag selector UI, and a new category-specific asset list component with debounced search. Supporting code updates include translation keys, icon mapping, asset query enhancements, and improved loading states and navigation for the asset list and cards. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ExplorePage
participant TagsComponent
participant ExploreCategory
participant AssetList
participant PortalsAssetsQuery
User->>ExplorePage: Navigates to /explore
ExplorePage->>TagsComponent: Renders tags (if not searching)
User->>TagsComponent: Selects a tag
TagsComponent->>ExploreCategory: Navigates to /explore/category/:category/:tag
ExploreCategory->>PortalsAssetsQuery: Fetch assets with category/tag
ExploreCategory->>AssetList: Render filtered assets with loading state
User->>ExploreCategory: Types in search bar
ExploreCategory->>AssetList: Debounced filter and update list
Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope changes found. Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🔭 Outside diff range comments (1)
src/lib/portals/utils.ts (1)
110-112: Fix missing tags parameter in recursive call.The recursive call for pagination is missing the
tagsparameter, which will cause subsequent pages to not be filtered by tags, leading to inconsistent results.Apply this diff to fix the issue:
- return fetchPortalsTokens({ chainIds, page: page + 1, accTokens: newTokens, limit }) + return fetchPortalsTokens({ chainIds, page: page + 1, accTokens: newTokens, limit, tags, sortBy, sortDirection, minApy })
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (14)
src/Routes/RoutesCommon.tsx(2 hunks)src/assets/translations/en/main.json(2 hunks)src/components/AssetSearch/components/AssetList.tsx(5 hunks)src/lib/market-service/market-service-manager.ts(1 hunks)src/lib/portals/types.ts(1 hunks)src/lib/portals/utils.ts(3 hunks)src/pages/Explore/Explore.tsx(2 hunks)src/pages/Explore/ExploreCategory.tsx(1 hunks)src/pages/Explore/components/AssetSearchRow.tsx(5 hunks)src/pages/Explore/components/CategoryCard.tsx(5 hunks)src/pages/Explore/components/Tags.tsx(1 hunks)src/pages/Explore/constant.tsx(1 hunks)src/pages/Markets/hooks/usePortalsAssetsQuery.ts(3 hunks)src/state/slices/assetsSlice/selectors.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/error-handling.mdc)
**/*.{ts,tsx}: ALWAYS use Result<T, E> pattern for error handling in swappers and APIs
ALWAYS use Ok() and Err() from @sniptt/monads for monadic error handling
ALWAYS use custom error classes from @shapeshiftoss/errors
ALWAYS provide meaningful error codes for internationalization
ALWAYS include relevant details in error objects
ALWAYS wrap async operations in try-catch blocks
ALWAYS use AsyncResultOf utility for converting promises to Results
ALWAYS provide fallback error handling
ALWAYS use timeoutMonadic for API calls
ALWAYS provide appropriate timeout values for API calls
ALWAYS handle timeout errors gracefully
ALWAYS validate inputs before processing
ALWAYS provide clear validation error messages
ALWAYS use early returns for validation failures
ALWAYS log errors for debugging
ALWAYS use structured logging for errors
ALWAYS include relevant context in error logs
Throwing errors instead of using monadic patterns is an anti-pattern
Missing try-catch blocks for async operations is an anti-pattern
Generic error messages without context are an anti-pattern
Not handling specific error types is an anti-pattern
Missing timeout handling is an anti-pattern
No input validation is an anti-pattern
Poor error logging is an anti-pattern
Using any for error types is an anti-pattern
Missing error codes for internationalization is an anti-pattern
No fallback error handling is an anti-pattern
Console.error without structured logging is an anti-pattern
**/*.{ts,tsx}: ALWAYS use camelCase for variables, functions, and methods
ALWAYS use descriptive names that explain the purpose for variables and functions
ALWAYS use verb prefixes for functions that perform actions
ALWAYS use PascalCase for types, interfaces, and enums
ALWAYS use descriptive names that indicate the structure for types, interfaces, and enums
ALWAYS use suffixes like Props, State, Config, Type when appropriate for types and interfaces
ALWAYS use UPPER_SNAKE_CASE for constants and configuration values
ALWAYS use d...
Files:
src/state/slices/assetsSlice/selectors.tssrc/pages/Explore/Explore.tsxsrc/pages/Explore/constant.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/lib/portals/types.tssrc/lib/market-service/market-service-manager.tssrc/lib/portals/utils.tssrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Markets/hooks/usePortalsAssetsQuery.tssrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/naming-conventions.mdc)
**/*: ALWAYS use appropriate file extensions
Flag files without kebab-case
Files:
src/state/slices/assetsSlice/selectors.tssrc/pages/Explore/Explore.tsxsrc/pages/Explore/constant.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/lib/portals/types.tssrc/lib/market-service/market-service-manager.tssrc/lib/portals/utils.tssrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/assets/translations/en/main.jsonsrc/pages/Markets/hooks/usePortalsAssetsQuery.tssrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/react-best-practices.mdc)
USE Redux only for global state shared across multiple places
Files:
src/state/slices/assetsSlice/selectors.tssrc/pages/Explore/Explore.tsxsrc/pages/Explore/constant.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/lib/portals/types.tssrc/lib/market-service/market-service-manager.tssrc/lib/portals/utils.tssrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Markets/hooks/usePortalsAssetsQuery.tssrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
**/*.tsx
📄 CodeRabbit Inference Engine (.cursor/rules/error-handling.mdc)
**/*.tsx: ALWAYS wrap components in error boundaries
ALWAYS provide user-friendly fallback components in error boundaries
ALWAYS log errors for debugging in error boundaries
ALWAYS use useErrorToast hook for displaying errors
ALWAYS provide translated error messages in error toasts
ALWAYS handle different error types appropriately in error toasts
Missing error boundaries in React components is an anti-pattern
**/*.tsx: ALWAYS use PascalCase for React component names
ALWAYS use descriptive names that indicate the component's purpose
ALWAYS match the component name to the file name
Flag components without PascalCase
Flag default exports for components
Files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/constant.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
**/*.{tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/react-best-practices.mdc)
**/*.{tsx,jsx}: ALWAYS useuseMemofor expensive computations, object/array creations, and filtered data
ALWAYS useuseMemofor derived values and computed properties
ALWAYS useuseMemofor conditional values and simple transformations
ALWAYS useuseCallbackfor event handlers and functions passed as props
ALWAYS useuseCallbackfor any function that could be passed as a prop or dependency
ALWAYS include all dependencies inuseEffect,useMemo,useCallbackdependency arrays
NEVER use// eslint-disable-next-line react-hooks/exhaustive-depsunless absolutely necessary
ALWAYS explain why dependencies are excluded if using eslint disable
ALWAYS use named exports for components
NEVER use default exports for components
KEEP component files under 200 lines when possible
BREAK DOWN large components into smaller, reusable pieces
EXTRACT complex logic into custom hooks
USE local state for component-level state
LIFT state up when needed across multiple components
USE Context for avoiding prop drilling
ALWAYS wrap components in error boundaries for production
ALWAYS handle async errors properly
ALWAYS provide user-friendly error messages
ALWAYS use virtualization for lists with 100+ items
ALWAYS implement proper key props for list items
ALWAYS lazy load heavy components
ALWAYS use React.lazy for code splitting
Components receiving props are wrapped withmemo
Files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/constant.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
**/use*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/naming-conventions.mdc)
**/use*.{ts,tsx}: ALWAYS use use prefix for custom hooks
ALWAYS use descriptive names that indicate the hook's purpose
ALWAYS use camelCase after the use prefix for custom hooks
Files:
src/pages/Markets/hooks/usePortalsAssetsQuery.ts
🧠 Learnings (59)
📓 Common learnings
Learnt from: NeOMakinG
PR: shapeshift/web#10136
File: src/lib/asset-service/service/encodedRelatedAssetIndex.json:1-1
Timestamp: 2025-07-29T10:22:27.037Z
Learning: PRs with titles starting with "feat: regenerate asset data" are routine daily asset updates that don't need detailed code analysis. Users prefer to skip automated reviews for these maintenance PRs using coderabbitai ignore.
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:54-72
Timestamp: 2025-08-06T11:02:09.501Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG indicated that memoizing the ExploreCard component would be unnecessary, questioning "why would we memoize that", suggesting that like CategoryCard, this component doesn't benefit from memoization despite receiving props, likely due to its specific usage patterns in the carousel with static content.
Learnt from: NeOMakinG
PR: shapeshift/web#10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
📚 Learning: applies to packages/swapper/src/swappers/*/{*.ts,endpoints.ts} : verify chain id filtering in filter...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-07-24T09:43:11.699Z
Learning: Applies to packages/swapper/src/swappers/*/{*.ts,endpoints.ts} : Verify chain ID filtering in filterAssetIdsBySellable and filterBuyAssetsBySellAssetId methods.
Applied to files:
src/state/slices/assetsSlice/selectors.tssrc/pages/Explore/components/AssetSearchRow.tsxsrc/lib/market-service/market-service-manager.tssrc/pages/Markets/hooks/usePortalsAssetsQuery.tssrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: the assetid type from '@shapeshiftoss/caip' package is a string type alias, so it can be used direct...
Learnt from: premiumjibles
PR: shapeshift/web#10187
File: src/state/slices/preferencesSlice/selectors.ts:21-25
Timestamp: 2025-08-05T23:36:13.214Z
Learning: The AssetId type from 'shapeshiftoss/caip' package is a string type alias, so it can be used directly as a return type for cache key resolvers in re-reselect selectors without needing explicit string conversion.
Applied to files:
src/state/slices/assetsSlice/selectors.tssrc/pages/Markets/hooks/usePortalsAssetsQuery.ts
📚 Learning: applies to **/*.{ts,tsx} : flag renamed imports without good reason...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.{ts,tsx} : Flag renamed imports without good reason
Applied to files:
src/state/slices/assetsSlice/selectors.tssrc/pages/Explore/Explore.tsxsrc/Routes/RoutesCommon.tsx
📚 Learning: in the shapeshift/web codebase, component imports use direct file paths like '@/components/component...
Learnt from: premiumjibles
PR: shapeshift/web#10187
File: src/pages/Assets/Asset.tsx:1-1
Timestamp: 2025-08-05T22:41:35.473Z
Learning: In the shapeshift/web codebase, component imports use direct file paths like '@/components/ComponentName/ComponentName' rather than barrel exports. The AssetAccountDetails component should be imported as '@/components/AssetAccountDetails/AssetAccountDetails', not from a directory index.
Applied to files:
src/state/slices/assetsSlice/selectors.tssrc/pages/Explore/Explore.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.{ts,tsx} : always use descriptive import names...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use descriptive import names
Applied to files:
src/state/slices/assetsSlice/selectors.ts
📚 Learning: applies to **/*.{ts,tsx} : always avoid renaming imports unless necessary...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS avoid renaming imports unless necessary
Applied to files:
src/state/slices/assetsSlice/selectors.ts
📚 Learning: applies to packages/swapper/src/swappers/*/{*.ts,endpoints.ts} : avoid side effects in swap logic wi...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-07-24T09:43:11.699Z
Learning: Applies to packages/swapper/src/swappers/*/{*.ts,endpoints.ts} : Avoid side effects in swap logic within swapper implementation files.
Applied to files:
src/state/slices/assetsSlice/selectors.ts
📚 Learning: applies to **/*.{ts,tsx} : utility types are used for common transformations...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : Utility types are used for common transformations
Applied to files:
src/state/slices/assetsSlice/selectors.ts
📚 Learning: applies to **/*.{ts,tsx} : always use named exports for components and functions...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use named exports for components and functions
Applied to files:
src/state/slices/assetsSlice/selectors.tssrc/pages/Explore/components/Tags.tsx
📚 Learning: applies to packages/swapper/src/index.ts : export unique functions/types from packages/swapper/src/i...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-07-24T09:43:11.699Z
Learning: Applies to packages/swapper/src/index.ts : Export unique functions/types from packages/swapper/src/index.ts if needed.
Applied to files:
src/state/slices/assetsSlice/selectors.ts
📚 Learning: in src/state/apis/swapper/helpers/swapperapihelpers.ts, the getstate parameter in processquoteresult...
Learnt from: premiumjibles
PR: shapeshift/web#10154
File: src/state/apis/swapper/helpers/swapperApiHelpers.ts:57-60
Timestamp: 2025-07-31T03:51:48.479Z
Learning: In src/state/apis/swapper/helpers/swapperApiHelpers.ts, the getState parameter in processQuoteResultWithRatios uses `() => unknown` type instead of `() => ReduxState` to avoid type compatibility issues elsewhere in the codebase.
Applied to files:
src/state/slices/assetsSlice/selectors.ts
📚 Learning: in src/pages/explore/explore.tsx, neomaking prefers keeping complex height calculations inline rathe...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:174-178
Timestamp: 2025-08-06T09:47:29.865Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG prefers keeping complex height calculations inline rather than extracting them to useMemo, prioritizing perceived performance/execution speed over code readability, even when the calculation would only run when the dependency (isSearching) changes.
Applied to files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: in src/pages/explore/explore.tsx, neomaking indicated that memoizing the explorecard component would...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:54-72
Timestamp: 2025-08-06T11:02:09.501Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG indicated that memoizing the ExploreCard component would be unnecessary, questioning "why would we memoize that", suggesting that like CategoryCard, this component doesn't benefit from memoization despite receiving props, likely due to its specific usage patterns in the carousel with static content.
Applied to files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsx
📚 Learning: in src/pages/explore/explore.tsx, neomaking questioned the suggestion to memoize a simple static car...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:81-83
Timestamp: 2025-08-06T11:44:30.697Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG questioned the suggestion to memoize a simple static carouselOptions object ({ loop: true }), indicating that static objects that never change should remain as module-level constants rather than being memoized inside components, as memoization would add unnecessary overhead for truly static values.
Applied to files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/constant.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsx
📚 Learning: applies to **/*.tsx : flag default exports for components...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.tsx : Flag default exports for components
Applied to files:
src/pages/Explore/Explore.tsx
📚 Learning: applies to **/*.{tsx,jsx} : extract complex logic into custom hooks...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : EXTRACT complex logic into custom hooks
Applied to files:
src/pages/Explore/Explore.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: in src/pages/explore/components/categorycard.tsx, neomaking indicated that wrapping the categorycard...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/components/CategoryCard.tsx:27-196
Timestamp: 2025-08-06T09:46:50.860Z
Learning: In src/pages/Explore/components/CategoryCard.tsx, NeOMakinG indicated that wrapping the CategoryCard component with React.memo would be "quite useless in this case", suggesting that memoization is not beneficial for this particular component despite it receiving props, likely due to its specific usage patterns or context.
Applied to files:
src/pages/Explore/Explore.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsx
📚 Learning: applies to **/*.tsx : always use descriptive names that indicate the component's purpose...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.tsx : ALWAYS use descriptive names that indicate the component's purpose
Applied to files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/ExploreCategory.tsx
📚 Learning: applies to **/*.{tsx,jsx} : break down large components into smaller, reusable pieces...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : BREAK DOWN large components into smaller, reusable pieces
Applied to files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/components/AssetSearchRow.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.tsx : missing error boundaries in react components is an anti-pattern...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-08-03T22:09:37.542Z
Learning: Applies to **/*.tsx : Missing error boundaries in React components is an anti-pattern
Applied to files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/ExploreCategory.tsx
📚 Learning: in the shapeshift web app, css custom properties like `--safe-area-inset-top` and `--safe-area-inset...
Learnt from: NeOMakinG
PR: shapeshift/web#10133
File: src/components/MultiHopTrade/components/SharedTradeInput/SharedTradeInput.tsx:37-40
Timestamp: 2025-07-29T08:57:09.276Z
Learning: In the ShapeShift web app, CSS custom properties like `--safe-area-inset-top` and `--safe-area-inset-bottom` are centrally initialized to '0px' in src/theme/theme.tsx within the global body styles. The mobile app overrides these values when running in mobile app scope. This architectural approach eliminates the need for fallback values in var() expressions throughout the codebase, since the variables are guaranteed to be defined.
Applied to files:
src/pages/Explore/Explore.tsx
📚 Learning: in the shapeshift web app's mobile header architecture, the `--mobile-header-offset` css variable re...
Learnt from: NeOMakinG
PR: shapeshift/web#10079
File: src/pages/Dashboard/components/DashboardHeader/DashboardHeaderWrapper.tsx:8-11
Timestamp: 2025-07-24T11:29:00.743Z
Learning: In the ShapeShift web app's mobile header architecture, the `--mobile-header-offset` CSS variable represents the total height of the entire mobile header, while the 56px paddingTop in DashboardHeaderWrapper is specifically for spacing the top bar content area only. These serve different purposes and should not be conflated - the header offset is for positioning the entire header, while the paddingTop is for internal content spacing.
Applied to files:
src/pages/Explore/Explore.tsx
📚 Learning: in the shapeshift web app's mobile header implementation, dynamically calculating the top bar height...
Learnt from: NeOMakinG
PR: shapeshift/web#10079
File: src/pages/Dashboard/components/DashboardHeader/DashboardHeaderWrapper.tsx:8-11
Timestamp: 2025-07-24T11:29:49.740Z
Learning: In the ShapeShift web app's mobile header implementation, dynamically calculating the top bar height for paddingTop would introduce maintenance complexity because the measured height might include safe area padding, which would be incorrect for the spacing use case. The hardcoded 56px approach is preferred over dynamic calculations to avoid this complexity and maintain code simplicity.
Applied to files:
src/pages/Explore/Explore.tsx
📚 Learning: applies to **/*.{tsx,jsx} : always use virtualization for lists with 100+ items...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use virtualization for lists with 100+ items
Applied to files:
src/pages/Explore/Explore.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.{ts,tsx} : enums are used for constants...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : Enums are used for constants
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: applies to **/*.{ts,tsx} : using strings instead of enums for constants...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : Using strings instead of enums for constants
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: applies to packages/swapper/src/{constants,types}.ts : register new swappers in packages/swapper/src...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-07-24T09:43:11.699Z
Learning: Applies to packages/swapper/src/{constants,types}.ts : Register new swappers in packages/swapper/src/constants.ts and add them to the SwapperName enum in packages/swapper/src/types.ts.
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: applies to **/*.{ts,tsx} : always group related constants together...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS group related constants together
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: applies to **/*.{ts,tsx} : always use enums for constants...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use enums for constants
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: check registry entry in constants.ts during code review....
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-07-24T09:43:11.699Z
Learning: Check registry entry in constants.ts during code review.
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: applies to **/*.{ts,tsx} : prefer use enums for constants, especially on types, statuses, codes...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : PREFER use enums for constants, especially on types, statuses, codes
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: applies to **/*.{ts,tsx} : always use descriptive enum names...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use descriptive enum names
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: applies to **/*.{ts,tsx} : always use descriptive names that explain the value's purpose for constan...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use descriptive names that explain the value's purpose for constants
Applied to files:
src/pages/Explore/constant.tsx
📚 Learning: in src/components/markettablevirtualized/marketstablevirtualized.tsx, neomaking prefers keeping the ...
Learnt from: NeOMakinG
PR: shapeshift/web#10148
File: src/components/MarketTableVirtualized/MarketsTableVirtualized.tsx:88-91
Timestamp: 2025-07-30T20:57:48.176Z
Learning: In src/components/MarketTableVirtualized/MarketsTableVirtualized.tsx, NeOMakinG prefers keeping the hardcoded overscan value (40) over dynamic calculation based on viewport height, prioritizing code simplicity over precision when the current approach works effectively.
Applied to files:
src/pages/Explore/components/AssetSearchRow.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: in src/components/multihoptrade/components/tradeconfirm/components/expandablesteppersteps.tsx, the c...
Learnt from: NeOMakinG
PR: shapeshift/web#10139
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx:109-115
Timestamp: 2025-07-29T15:04:28.083Z
Learning: In src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx, the component is used under an umbrella that 100% of the time contains the quote, making the type assertion `activeTradeQuote?.steps[currentHopIndex] as TradeQuoteStep` safe. Adding conditional returns before hooks would violate React's Rules of Hooks.
Applied to files:
src/pages/Explore/components/AssetSearchRow.tsxsrc/Routes/RoutesCommon.tsxsrc/pages/Explore/components/Tags.tsxsrc/pages/Explore/components/CategoryCard.tsxsrc/pages/Explore/ExploreCategory.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.{ts,tsx} : always use descriptive property names...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use descriptive property names
Applied to files:
src/pages/Explore/components/AssetSearchRow.tsx
📚 Learning: applies to **/*.{ts,tsx} : function types are properly defined...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : Function types are properly defined
Applied to files:
src/lib/portals/utils.ts
📚 Learning: applies to **/*.{ts,tsx} : optional properties are marked with `?`...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : Optional properties are marked with `?`
Applied to files:
src/lib/portals/utils.tssrc/pages/Markets/hooks/usePortalsAssetsQuery.ts
📚 Learning: in src/lib/moralis.ts, gomesalexandre doesn't require explicit return type annotations for simple ut...
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/lib/moralis.ts:24-30
Timestamp: 2025-08-07T12:10:57.967Z
Learning: In src/lib/moralis.ts, gomesalexandre doesn't require explicit return type annotations for simple utility functions like startMoralis, preferring to keep them concise when the return type is obvious from context.
Applied to files:
src/lib/portals/utils.ts
📚 Learning: applies to **/*.{tsx,jsx} : always use named exports for components...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use named exports for components
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.{tsx,jsx} : never use `// eslint-disable-next-line react-hooks/exhaustive-deps` unle...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : NEVER use `// eslint-disable-next-line react-hooks/exhaustive-deps` unless absolutely necessary
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: the shapeshift team practices aggressive memoization in react components as documented in .cursor/ru...
Learnt from: NeOMakinG
PR: shapeshift/web#10128
File: .cursor/rules/react-best-practices.mdc:8-14
Timestamp: 2025-07-29T10:27:23.424Z
Learning: The ShapeShift team practices aggressive memoization in React components as documented in .cursor/rules/react-best-practices.mdc. They use useMemo for all transformations, derived values, and conditional values, and useCallback for all event handlers and functions that could be passed as props. This approach was adopted after experiencing performance issues ("had hard time") and is their current established practice, though they acknowledge it may evolve in the future.
Applied to files:
src/pages/Explore/components/CategoryCard.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.{tsx,jsx} : always use `usememo` for conditional values and simple transformations...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useMemo` for conditional values and simple transformations
Applied to files:
src/pages/Explore/components/CategoryCard.tsx
📚 Learning: applies to **/*.{tsx,jsx} : always use `usememo` for expensive computations, object/array creations,...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useMemo` for expensive computations, object/array creations, and filtered data
Applied to files:
src/pages/Explore/components/CategoryCard.tsx
📚 Learning: applies to **/*.{tsx,jsx} : lift state up when needed across multiple components...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : LIFT state up when needed across multiple components
Applied to files:
src/pages/Explore/components/CategoryCard.tsxsrc/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/use*.{ts,tsx} : always use camelcase after the use prefix for custom hooks...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/use*.{ts,tsx} : ALWAYS use camelCase after the use prefix for custom hooks
Applied to files:
src/pages/Explore/components/CategoryCard.tsxsrc/pages/Markets/hooks/usePortalsAssetsQuery.ts
📚 Learning: applies to **/use*.{ts,tsx} : always use descriptive names that indicate the hook's purpose...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/use*.{ts,tsx} : ALWAYS use descriptive names that indicate the hook's purpose
Applied to files:
src/pages/Explore/components/CategoryCard.tsxsrc/pages/Markets/hooks/usePortalsAssetsQuery.ts
📚 Learning: in the shapeshift web app carousel dot buttons (src/components/carousel/dotbutton.tsx), the blue.500...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/components/Carousel/DotButton.tsx:6-9
Timestamp: 2025-08-06T09:45:26.568Z
Learning: In the ShapeShift web app carousel dot buttons (src/components/Carousel/DotButton.tsx), the blue.500 color is intentionally used for both light and dark themes rather than using adaptive theming with useColorModeValue. This is a deliberate design decision to maintain consistent visual appearance for carousel navigation elements.
Applied to files:
src/pages/Explore/components/CategoryCard.tsx
📚 Learning: in the shapeshift web repository, translation workflow follows a two-step process: 1) first pr adds ...
Learnt from: 0xApotheosis
PR: shapeshift/web#10073
File: src/components/Layout/Header/ActionCenter/components/Details/ClaimDetails.tsx:10-11
Timestamp: 2025-07-24T21:05:13.642Z
Learning: In the ShapeShift web repository, translation workflow follows a two-step process: 1) First PR adds only English translations to src/assets/translations/en/main.json, 2) Globalization team handles follow-up PRs to add keys to remaining language files (de, es, fr, id, ja, ko, pt, ru, tr, uk, zh). Don't suggest verifying all locale files simultaneously during initial feature PRs.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: when reviewing json diffs in translation files, distinguish between syntax-required changes (like ad...
Learnt from: gomesalexandre
PR: shapeshift/web#10154
File: src/assets/translations/en/main.json:1004-1006
Timestamp: 2025-08-04T13:33:22.878Z
Learning: When reviewing JSON diffs in translation files, distinguish between syntax-required changes (like adding commas to existing lines to accommodate new entries) versus actual content modifications. A comma addition to an existing line is often just JSON syntax infrastructure, not an intentional change to that line's content.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: gomesalexandre considers translation key consolidation (like multiple keys for "view on explorer" fu...
Learnt from: gomesalexandre
PR: shapeshift/web#10187
File: src/assets/translations/en/main.json:205-206
Timestamp: 2025-08-06T08:58:09.096Z
Learning: gomesalexandre considers translation key consolidation (like multiple keys for "view on explorer" functionality) as nice-to-have improvements rather than critical issues. The team doesn't prioritize i18n consistency across the board currently, and they prefer to handle such consolidation suggestions at their own discretion based on other priorities.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: applies to **/!use*.{ts,tsx} : flag custom hooks without use prefix...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/!use*.{ts,tsx} : Flag custom hooks without use prefix
Applied to files:
src/pages/Markets/hooks/usePortalsAssetsQuery.ts
📚 Learning: applies to **/use*.{ts,tsx} : always use use prefix for custom hooks...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/use*.{ts,tsx} : ALWAYS use use prefix for custom hooks
Applied to files:
src/pages/Markets/hooks/usePortalsAssetsQuery.ts
📚 Learning: applies to **/*.{tsx,jsx} : always implement proper key props for list items...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS implement proper key props for list items
Applied to files:
src/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.{tsx,jsx} : always lazy load heavy components...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS lazy load heavy components
Applied to files:
src/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.{tsx,jsx} : use context for avoiding prop drilling...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : USE Context for avoiding prop drilling
Applied to files:
src/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.{tsx,jsx} : components receiving props are wrapped with `memo`...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : Components receiving props are wrapped with `memo`
Applied to files:
src/components/AssetSearch/components/AssetList.tsx
📚 Learning: applies to **/*.tsx : always provide user-friendly fallback components in error boundaries...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-08-03T22:09:37.542Z
Learning: Applies to **/*.tsx : ALWAYS provide user-friendly fallback components in error boundaries
Applied to files:
src/components/AssetSearch/components/AssetList.tsx
🧬 Code Graph Analysis (4)
src/pages/Explore/Explore.tsx (1)
src/pages/Explore/components/Tags.tsx (1)
Tags(18-115)
src/Routes/RoutesCommon.tsx (1)
src/pages/Explore/ExploreCategory.tsx (1)
ExploreCategory(34-227)
src/pages/Explore/components/Tags.tsx (1)
src/pages/Explore/constant.tsx (1)
exploreTagsIcons(16-24)
src/components/AssetSearch/components/AssetList.tsx (2)
src/pages/Markets/hooks/usePortalsAssetsQuery.ts (1)
PortalsAssets(15-19)src/state/slices/assetsSlice/assetsSlice.ts (1)
assets(42-64)
⏰ 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: Install and Cache
🔇 Additional comments (25)
src/pages/Explore/constant.tsx (1)
6-14: Well-structured enum with appropriate naming conventions.The
PortalsTagsenum follows TypeScript best practices with descriptive PascalCase naming and string values suitable for URL parameters and API calls.src/state/slices/assetsSlice/selectors.ts (1)
13-15: LGTM - Import formatting improvement.The change from single-line to multi-line import is a formatting improvement that maintains consistency with other imports in the file.
src/pages/Explore/Explore.tsx (2)
27-27: LGTM - Clean import of the Tags component.The import follows established patterns in the codebase and correctly adds the new Tags component.
205-205: Well-implemented conditional rendering for Tags component.The Tags component is appropriately rendered only when not searching, which provides a clean UX by hiding category filters during search operations. This aligns well with the search-focused state management in the component.
src/pages/Markets/hooks/usePortalsAssetsQuery.ts (2)
27-28: Well-designed optional parameter addition.The
tagsparameter is properly typed as optional (string[]) and maintains backward compatibility while enabling new tag-based filtering functionality.Also applies to: 34-35
47-47: Proper cache key management and parameter propagation.The
tagsparameter is correctly included in the query key to ensure cache differentiation based on tags, and properly passed through to thefetchPortalsTokensfunction call.Also applies to: 60-60
src/Routes/RoutesCommon.tsx (2)
24-24: LGTM! Import follows established patterns.The import uses the correct direct file path pattern consistent with the codebase conventions.
233-244: LGTM! Route configuration is well-structured.The nested routes properly support the category and tag filtering functionality:
- Both routes correctly render the
ExploreCategorycomponent- Routes are appropriately marked as
hide: truesince they're sub-routes- Parameter names
:categoryand:tagalign with the component's expected parameters- The optional tag parameter on Line 240 enables flexible navigation
src/lib/portals/utils.ts (1)
25-34: LGTM! Parameter addition follows good TypeScript practices.The
tagsparameter is properly:
- Typed as optional
string[]- Added to the function signature and destructured parameters
- Included in the API request parameters
Also applies to: 54-54
src/assets/translations/en/main.json (1)
133-134:seeMorekey addition looks correctKey is unique within the
commonblock, JSON syntax is preserved, and the label matches surrounding style (title-case).
No further action required.src/lib/market-service/market-service-manager.ts (1)
72-86: LGTM! Simplified provider lookup logic.The removal of special prioritization for pool tokens makes the provider lookup more uniform and predictable. The method now respects the provider order defined in the constructor for all asset types.
src/pages/Explore/components/AssetSearchRow.tsx (2)
37-37: Props restructuring looks good.The extraction of
portalsAssetsfrom thedataprop aligns with the updated component usage pattern across the codebase.
169-177: Good addition of text overflow handling.The CSS properties for handling text overflow (
textOverflow,whiteSpace,maxWidth,overflow) properly constrain long symbol names and prevent layout issues.src/pages/Explore/components/Tags.tsx (2)
31-36: Navigation uses fixed category path.The navigation path uses a hardcoded
MarketsCategories.OneClickDeficategory. This is acceptable if the Tags component is specifically designed for the OneClickDefi explore page, but consider making it configurable if reusability across different categories is needed in the future.
45-68: Well-implemented auto-scroll behavior.The auto-scroll logic properly centers the active tag button when it's outside the visible area, providing a good user experience with smooth scrolling.
src/pages/Explore/components/CategoryCard.tsx (2)
63-66: Sorting by volume aligns with PR objectives.The change from APY to Volume sorting ensures the most actively traded assets appear first, which provides better asset discovery for users.
205-212: Good addition of navigation button.The "See More" button is properly positioned and provides clear navigation to the full category page, improving the user experience for exploring more assets.
src/pages/Explore/ExploreCategory.tsx (2)
107-122: Well-implemented search with appropriate filtering.The search functionality properly:
- Filters out low market cap assets to avoid spam
- Uses fuzzy matching for better user experience
- Limits results to 20 for performance
- Matches against name, symbol, and assetId fields
216-221: Comprehensive loading state management.Good practice combining both
isLoadingandisFetchingstates from multiple queries to provide accurate loading feedback during initial load and data refetching.src/components/AssetSearch/components/AssetList.tsx (6)
2-2: LGTM! Import additions are appropriate.The new imports (
Flex,Skeletonfrom Chakra UI andrangefrom lodash) are correctly added to support the loading skeleton implementation, and thePortalsAssetstype import provides proper typing.Also applies to: 4-4, 17-17
25-26: LGTM! Optional props are properly typed.The new optional props
isLoadingandportalsAssetsare correctly typed with appropriate defaults and optional indicators.
42-43: LGTM! Props destructuring with proper defaults.The component correctly destructures the new props with appropriate default values (
isLoading = falseand optionalportalsAssets).
79-81: LGTM! Memoization dependencies are correctly updated.The
itemDatauseMemo correctly includesportalsAssetsin the dependency array, ensuring proper memoization when portalsAssets changes. This follows the team's aggressive memoization practices.
86-106: LGTM! Loading skeleton implementation is well-structured.The loading state implementation provides a good user experience with:
- Three skeleton rows mimicking the actual asset row structure
- Proper layout with icon, name/balance placeholders, and price information
- Consistent spacing and styling
- Early return pattern for clean conditional rendering
The skeleton structure accurately represents the actual asset row layout.
131-131: LGTM! Dependency array correctly updated.The
renderContentcallback properly includesisLoadingin its dependency array to ensure the component re-renders when the loading state changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/pages/Explore/components/Tags.tsx (1)
89-115: ESLint suppressions indicate missing memoization - but based on previous feedback, this may be acceptable.The inline ref callback and onClick handler have ESLint suppressions. While these could be memoized with useCallback, previous learnings from this developer suggest they prefer keeping inline handlers in some cases for simplicity.
Based on previous feedback from NeOMakinG about memoization preferences, the current approach with ESLint suppressions may be intentional for this component's usage pattern.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
src/pages/Explore/components/Tags.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/error-handling.mdc)
**/*.{ts,tsx}: ALWAYS use Result<T, E> pattern for error handling in swappers and APIs
ALWAYS use Ok() and Err() from @sniptt/monads for monadic error handling
ALWAYS use custom error classes from @shapeshiftoss/errors
ALWAYS provide meaningful error codes for internationalization
ALWAYS include relevant details in error objects
ALWAYS wrap async operations in try-catch blocks
ALWAYS use AsyncResultOf utility for converting promises to Results
ALWAYS provide fallback error handling
ALWAYS use timeoutMonadic for API calls
ALWAYS provide appropriate timeout values for API calls
ALWAYS handle timeout errors gracefully
ALWAYS validate inputs before processing
ALWAYS provide clear validation error messages
ALWAYS use early returns for validation failures
ALWAYS log errors for debugging
ALWAYS use structured logging for errors
ALWAYS include relevant context in error logs
Throwing errors instead of using monadic patterns is an anti-pattern
Missing try-catch blocks for async operations is an anti-pattern
Generic error messages without context are an anti-pattern
Not handling specific error types is an anti-pattern
Missing timeout handling is an anti-pattern
No input validation is an anti-pattern
Poor error logging is an anti-pattern
Using any for error types is an anti-pattern
Missing error codes for internationalization is an anti-pattern
No fallback error handling is an anti-pattern
Console.error without structured logging is an anti-pattern
**/*.{ts,tsx}: ALWAYS use camelCase for variables, functions, and methods
ALWAYS use descriptive names that explain the purpose for variables and functions
ALWAYS use verb prefixes for functions that perform actions
ALWAYS use PascalCase for types, interfaces, and enums
ALWAYS use descriptive names that indicate the structure for types, interfaces, and enums
ALWAYS use suffixes like Props, State, Config, Type when appropriate for types and interfaces
ALWAYS use UPPER_SNAKE_CASE for constants and configuration values
ALWAYS use d...
Files:
src/pages/Explore/components/Tags.tsx
**/*.tsx
📄 CodeRabbit Inference Engine (.cursor/rules/error-handling.mdc)
**/*.tsx: ALWAYS wrap components in error boundaries
ALWAYS provide user-friendly fallback components in error boundaries
ALWAYS log errors for debugging in error boundaries
ALWAYS use useErrorToast hook for displaying errors
ALWAYS provide translated error messages in error toasts
ALWAYS handle different error types appropriately in error toasts
Missing error boundaries in React components is an anti-pattern
**/*.tsx: ALWAYS use PascalCase for React component names
ALWAYS use descriptive names that indicate the component's purpose
ALWAYS match the component name to the file name
Flag components without PascalCase
Flag default exports for components
Files:
src/pages/Explore/components/Tags.tsx
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/naming-conventions.mdc)
**/*: ALWAYS use appropriate file extensions
Flag files without kebab-case
Files:
src/pages/Explore/components/Tags.tsx
**/*.{tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/react-best-practices.mdc)
**/*.{tsx,jsx}: ALWAYS useuseMemofor expensive computations, object/array creations, and filtered data
ALWAYS useuseMemofor derived values and computed properties
ALWAYS useuseMemofor conditional values and simple transformations
ALWAYS useuseCallbackfor event handlers and functions passed as props
ALWAYS useuseCallbackfor any function that could be passed as a prop or dependency
ALWAYS include all dependencies inuseEffect,useMemo,useCallbackdependency arrays
NEVER use// eslint-disable-next-line react-hooks/exhaustive-depsunless absolutely necessary
ALWAYS explain why dependencies are excluded if using eslint disable
ALWAYS use named exports for components
NEVER use default exports for components
KEEP component files under 200 lines when possible
BREAK DOWN large components into smaller, reusable pieces
EXTRACT complex logic into custom hooks
USE local state for component-level state
LIFT state up when needed across multiple components
USE Context for avoiding prop drilling
ALWAYS wrap components in error boundaries for production
ALWAYS handle async errors properly
ALWAYS provide user-friendly error messages
ALWAYS use virtualization for lists with 100+ items
ALWAYS implement proper key props for list items
ALWAYS lazy load heavy components
ALWAYS use React.lazy for code splitting
Components receiving props are wrapped withmemo
Files:
src/pages/Explore/components/Tags.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/react-best-practices.mdc)
USE Redux only for global state shared across multiple places
Files:
src/pages/Explore/components/Tags.tsx
🧠 Learnings (17)
📓 Common learnings
Learnt from: NeOMakinG
PR: shapeshift/web#10136
File: src/lib/asset-service/service/encodedRelatedAssetIndex.json:1-1
Timestamp: 2025-07-29T10:22:27.037Z
Learning: PRs with titles starting with "feat: regenerate asset data" are routine daily asset updates that don't need detailed code analysis. Users prefer to skip automated reviews for these maintenance PRs using coderabbitai ignore.
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:54-72
Timestamp: 2025-08-06T11:02:09.501Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG indicated that memoizing the ExploreCard component would be unnecessary, questioning "why would we memoize that", suggesting that like CategoryCard, this component doesn't benefit from memoization despite receiving props, likely due to its specific usage patterns in the carousel with static content.
Learnt from: NeOMakinG
PR: shapeshift/web#10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
📚 Learning: in src/pages/explore/explore.tsx, neomaking indicated that memoizing the explorecard component would...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:54-72
Timestamp: 2025-08-06T11:02:09.501Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG indicated that memoizing the ExploreCard component would be unnecessary, questioning "why would we memoize that", suggesting that like CategoryCard, this component doesn't benefit from memoization despite receiving props, likely due to its specific usage patterns in the carousel with static content.
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: in src/pages/explore/explore.tsx, neomaking prefers keeping complex height calculations inline rathe...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:174-178
Timestamp: 2025-08-06T09:47:29.865Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG prefers keeping complex height calculations inline rather than extracting them to useMemo, prioritizing perceived performance/execution speed over code readability, even when the calculation would only run when the dependency (isSearching) changes.
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: in src/pages/explore/components/categorycard.tsx, neomaking indicated that wrapping the categorycard...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/components/CategoryCard.tsx:27-196
Timestamp: 2025-08-06T09:46:50.860Z
Learning: In src/pages/Explore/components/CategoryCard.tsx, NeOMakinG indicated that wrapping the CategoryCard component with React.memo would be "quite useless in this case", suggesting that memoization is not beneficial for this particular component despite it receiving props, likely due to its specific usage patterns or context.
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.{tsx,jsx} : break down large components into smaller, reusable pieces...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : BREAK DOWN large components into smaller, reusable pieces
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.{tsx,jsx} : extract complex logic into custom hooks...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : EXTRACT complex logic into custom hooks
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.tsx : always use descriptive names that indicate the component's purpose...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.tsx : ALWAYS use descriptive names that indicate the component's purpose
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.tsx : missing error boundaries in react components is an anti-pattern...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-08-03T22:09:37.542Z
Learning: Applies to **/*.tsx : Missing error boundaries in React components is an anti-pattern
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: in src/pages/explore/explore.tsx, neomaking questioned the suggestion to memoize a simple static car...
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:81-83
Timestamp: 2025-08-06T11:44:30.697Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG questioned the suggestion to memoize a simple static carouselOptions object ({ loop: true }), indicating that static objects that never change should remain as module-level constants rather than being memoized inside components, as memoization would add unnecessary overhead for truly static values.
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.tsx : always use pascalcase for react component names...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.tsx : ALWAYS use PascalCase for React component names
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: in src/components/multihoptrade/components/tradeconfirm/components/expandablesteppersteps.tsx, the c...
Learnt from: NeOMakinG
PR: shapeshift/web#10139
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx:109-115
Timestamp: 2025-07-29T15:04:28.083Z
Learning: In src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx, the component is used under an umbrella that 100% of the time contains the quote, making the type assertion `activeTradeQuote?.steps[currentHopIndex] as TradeQuoteStep` safe. Adding conditional returns before hooks would violate React's Rules of Hooks.
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.{tsx,jsx} : always use `usecallback` for event handlers and functions passed as prop...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useCallback` for event handlers and functions passed as props
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.{tsx,jsx} : always use `usecallback` for any function that could be passed as a prop...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useCallback` for any function that could be passed as a prop or dependency
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.{tsx,jsx} : never use `// eslint-disable-next-line react-hooks/exhaustive-deps` unle...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : NEVER use `// eslint-disable-next-line react-hooks/exhaustive-deps` unless absolutely necessary
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.{tsx,jsx} : components receiving props are wrapped with `memo`...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : Components receiving props are wrapped with `memo`
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: in src/components/markettablevirtualized/marketstablevirtualized.tsx, neomaking prefers keeping the ...
Learnt from: NeOMakinG
PR: shapeshift/web#10148
File: src/components/MarketTableVirtualized/MarketsTableVirtualized.tsx:88-91
Timestamp: 2025-07-30T20:57:48.176Z
Learning: In src/components/MarketTableVirtualized/MarketsTableVirtualized.tsx, NeOMakinG prefers keeping the hardcoded overscan value (40) over dynamic calculation based on viewport height, prioritizing code simplicity over precision when the current approach works effectively.
Applied to files:
src/pages/Explore/components/Tags.tsx
📚 Learning: applies to **/*.{tsx,jsx} : always use virtualization for lists with 100+ items...
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:10:38.426Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use virtualization for lists with 100+ items
Applied to files:
src/pages/Explore/components/Tags.tsx
🧬 Code Graph Analysis (1)
src/pages/Explore/components/Tags.tsx (1)
src/pages/Explore/constant.tsx (1)
exploreTagsIcons(16-24)
⏰ 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: Install and Cache
🔇 Additional comments (8)
src/pages/Explore/components/Tags.tsx (8)
1-9: LGTM! Clean imports and proper organization.The imports are well-organized and follow proper naming conventions. All necessary dependencies are imported appropriately.
10-16: Good use of CSS-in-JS for scrollbar hiding.The containerSx object properly hides scrollbars across different browsers while maintaining functionality.
31-36: LGTM! Proper use of useCallback for navigation handler.The handleClick function is correctly memoized with useCallback and includes the navigate dependency.
38-43: LGTM! Proper memoization of style object.The activeStyle object is correctly memoized to prevent unnecessary re-renders.
45-71: LGTM! Well-implemented auto-scroll functionality.The useEffect properly handles scrolling the active tag into view with smooth behavior. The dependency array is correct and the logic handles edge cases well.
73-75: LGTM! Proper ref callback implementation.The handleButtonRef function is correctly memoized with useCallback and has the right dependencies.
77-118: LGTM! Well-structured JSX with proper styling and accessibility.The JSX structure is clean and follows good practices:
- Proper use of Chakra UI components and styling
- Accessible button implementation
- Good use of flexbox for layout
- Proper state management for active/inactive styles
- Translation integration works correctly
18-29: Component needs memoization and proper TypeScript types.The component receives no props but should be wrapped with
memoper coding guidelines. Additionally, explicit return type should be added.Apply this diff to add proper memoization and typing:
-export const Tags = () => { +export const Tags = memo((): JSX.Element => {Don't forget to add the import:
-import { useCallback, useEffect, useMemo, useRef } from 'react' +import { memo, useCallback, useEffect, useMemo, useRef } from 'react'⛔ Skipped due to learnings
Learnt from: CR PR: shapeshift/web#0 File: .cursor/rules/react-best-practices.mdc:0-0 Timestamp: 2025-08-03T22:10:38.426Z Learning: Applies to **/*.{tsx,jsx} : Components receiving props are wrapped with `memo`Learnt from: NeOMakinG PR: shapeshift/web#10191 File: src/pages/Explore/components/CategoryCard.tsx:27-196 Timestamp: 2025-08-06T09:46:50.860Z Learning: In src/pages/Explore/components/CategoryCard.tsx, NeOMakinG indicated that wrapping the CategoryCard component with React.memo would be "quite useless in this case", suggesting that memoization is not beneficial for this particular component despite it receiving props, likely due to its specific usage patterns or context.Learnt from: CR PR: shapeshift/web#0 File: .cursor/rules/react-best-practices.mdc:0-0 Timestamp: 2025-08-03T22:10:38.426Z Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useMemo` for conditional values and simple transformationsLearnt from: CR PR: shapeshift/web#0 File: .cursor/rules/react-best-practices.mdc:0-0 Timestamp: 2025-08-03T22:10:38.426Z Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useMemo` for expensive computations, object/array creations, and filtered dataLearnt from: CR PR: shapeshift/web#0 File: .cursor/rules/react-best-practices.mdc:0-0 Timestamp: 2025-08-03T22:10:38.426Z Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useMemo` for derived values and computed propertiesLearnt from: CR PR: shapeshift/web#0 File: .cursor/rules/react-best-practices.mdc:0-0 Timestamp: 2025-08-03T22:10:38.426Z Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useCallback` for any function that could be passed as a prop or dependencyLearnt from: CR PR: shapeshift/web#0 File: .cursor/rules/react-best-practices.mdc:0-0 Timestamp: 2025-08-03T22:10:38.426Z Learning: Applies to **/*.{tsx,jsx} : EXTRACT complex logic into custom hooksLearnt from: NeOMakinG PR: shapeshift/web#10191 File: src/pages/Explore/Explore.tsx:54-72 Timestamp: 2025-08-06T11:02:09.501Z Learning: In src/pages/Explore/Explore.tsx, NeOMakinG indicated that memoizing the ExploreCard component would be unnecessary, questioning "why would we memoize that", suggesting that like CategoryCard, this component doesn't benefit from memoization despite receiving props, likely due to its specific usage patterns in the carousel with static content.Learnt from: NeOMakinG PR: shapeshift/web#10128 File: .cursor/rules/react-best-practices.mdc:8-14 Timestamp: 2025-07-29T10:27:23.424Z Learning: The ShapeShift team practices aggressive memoization in React components as documented in .cursor/rules/react-best-practices.mdc. They use useMemo for all transformations, derived values, and conditional values, and useCallback for all event handlers and functions that could be passed as props. This approach was adopted after experiencing performance issues ("had hard time") and is their current established practice, though they acknowledge it may evolve in the future.Learnt from: CR PR: shapeshift/web#0 File: .cursor/rules/react-best-practices.mdc:0-0 Timestamp: 2025-08-03T22:10:38.426Z Learning: Applies to **/*.{tsx,jsx} : ALWAYS include all dependencies in `useEffect`, `useMemo`, `useCallback` dependency arraysLearnt from: NeOMakinG PR: shapeshift/web#10191 File: src/pages/Explore/Explore.tsx:174-178 Timestamp: 2025-08-06T09:47:29.865Z Learning: In src/pages/Explore/Explore.tsx, NeOMakinG prefers keeping complex height calculations inline rather than extracting them to useMemo, prioritizing perceived performance/execution speed over code readability, even when the calculation would only run when the dependency (isSearching) changes.
gomesalexandre
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conceptually looks sane to me - runtime test to follow
gomesalexandre
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
https://jam.dev/c/c592e28a-8cca-4eb3-802e-45e634aad076
Bit weird to have lending and liquid staking as discussed, as just holding those tokens doesn't make you have a lending position/liquid staking position in and by itself, but product concern which will take a few lines to nuke after
@shapeshift/product FYI, if we want to remove liquid staking and lending! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
src/assets/translations/en/main.json(2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*
📄 CodeRabbit Inference Engine (.cursor/rules/naming-conventions.mdc)
**/*: ALWAYS use appropriate file extensions
Flag files without kebab-case
Files:
src/assets/translations/en/main.json
🧠 Learnings (16)
📓 Common learnings
Learnt from: NeOMakinG
PR: shapeshift/web#10136
File: src/lib/asset-service/service/encodedRelatedAssetIndex.json:1-1
Timestamp: 2025-07-29T10:22:27.037Z
Learning: PRs with titles starting with "feat: regenerate asset data" are routine daily asset updates that don't need detailed code analysis. Users prefer to skip automated reviews for these maintenance PRs using coderabbitai ignore.
Learnt from: NeOMakinG
PR: shapeshift/web#10191
File: src/pages/Explore/Explore.tsx:54-72
Timestamp: 2025-08-06T11:02:09.501Z
Learning: In src/pages/Explore/Explore.tsx, NeOMakinG indicated that memoizing the ExploreCard component would be unnecessary, questioning "why would we memoize that", suggesting that like CategoryCard, this component doesn't benefit from memoization despite receiving props, likely due to its specific usage patterns in the carousel with static content.
Learnt from: NeOMakinG
PR: shapeshift/web#10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
📚 Learning: 2025-07-24T21:05:13.642Z
Learnt from: 0xApotheosis
PR: shapeshift/web#10073
File: src/components/Layout/Header/ActionCenter/components/Details/ClaimDetails.tsx:10-11
Timestamp: 2025-07-24T21:05:13.642Z
Learning: In the ShapeShift web repository, translation workflow follows a two-step process: 1) First PR adds only English translations to src/assets/translations/en/main.json, 2) Globalization team handles follow-up PRs to add keys to remaining language files (de, es, fr, id, ja, ko, pt, ru, tr, uk, zh). Don't suggest verifying all locale files simultaneously during initial feature PRs.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-04T13:33:22.878Z
Learnt from: gomesalexandre
PR: shapeshift/web#10154
File: src/assets/translations/en/main.json:1004-1006
Timestamp: 2025-08-04T13:33:22.878Z
Learning: When reviewing JSON diffs in translation files, distinguish between syntax-required changes (like adding commas to existing lines to accommodate new entries) versus actual content modifications. A comma addition to an existing line is often just JSON syntax infrastructure, not an intentional change to that line's content.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-06T08:58:09.096Z
Learnt from: gomesalexandre
PR: shapeshift/web#10187
File: src/assets/translations/en/main.json:205-206
Timestamp: 2025-08-06T08:58:09.096Z
Learning: gomesalexandre considers translation key consolidation (like multiple keys for "view on explorer" functionality) as nice-to-have improvements rather than critical issues. The team doesn't prioritize i18n consistency across the board currently, and they prefer to handle such consolidation suggestions at their own discretion based on other priorities.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-07-24T13:49:39.586Z
Learnt from: firebomb1
PR: shapeshift/web#0
File: :0-0
Timestamp: 2025-07-24T13:49:39.586Z
Learning: Translation-only PRs that sync localization files (like biweekly translation updates) typically don't benefit from detailed code analysis suggestions, and users may prefer to use coderabbitai ignore for such routine maintenance PRs.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-03T22:11:30.833Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use descriptive enum names
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-07-24T09:43:11.699Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-07-24T09:43:11.699Z
Learning: Check registry entry in constants.ts during code review.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-07-24T09:43:11.699Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-07-24T09:43:11.699Z
Learning: Applies to packages/swapper/src/swappers/*/{*.ts,endpoints.ts} : Verify chain ID filtering in filterAssetIdsBySellable and filterBuyAssetsBySellAssetId methods.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-03T22:11:30.833Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : String enums are used for better debugging
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-03T22:11:30.833Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use string enums for better debugging
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-03T22:09:37.542Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-08-03T22:09:37.542Z
Learning: Applies to **/*.{ts,tsx} : Missing error codes for internationalization is an anti-pattern
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-03T22:10:11.424Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/naming-conventions.mdc:0-0
Timestamp: 2025-08-03T22:10:11.424Z
Learning: Applies to **/*.{ts,tsx} : Flag abbreviations that aren't widely understood
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-03T22:09:37.542Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-08-03T22:09:37.542Z
Learning: Applies to **/swapper/**/*.{ts,tsx} : ALWAYS use TradeQuoteError enum for error codes in swapper errors
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-08-03T22:11:30.833Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-08-03T22:11:30.833Z
Learning: Applies to **/*.{ts,tsx} : PREFER use enums for constants, especially on types, statuses, codes
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-07-29T10:22:27.037Z
Learnt from: NeOMakinG
PR: shapeshift/web#10136
File: src/lib/asset-service/service/encodedRelatedAssetIndex.json:1-1
Timestamp: 2025-07-29T10:22:27.037Z
Learning: PRs with titles starting with "feat: regenerate asset data" are routine daily asset updates that don't need detailed code analysis. Users prefer to skip automated reviews for these maintenance PRs using coderabbitai ignore.
Applied to files:
src/assets/translations/en/main.json
📚 Learning: 2025-07-24T09:43:11.699Z
Learnt from: CR
PR: shapeshift/web#0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-07-24T09:43:11.699Z
Learning: Applies to packages/swapper/src/swappers/*/{*.ts,endpoints.ts} : Include comments explaining swap logic in swapper implementation files.
Applied to files:
src/assets/translations/en/main.json
⏰ 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: Install and Cache
🔇 Additional comments (1)
src/assets/translations/en/main.json (1)
133-133:"seeMore"key looks goodKey/value pair added correctly; no further issues spotted.
| }, | ||
| "tags": { | ||
| "liquid-staking": "Liquid Staking", | ||
| "yield": "Yield", | ||
| "lending": "Lending", | ||
| "rwa": "RWA", | ||
| "yield-aggregator": "Yield Aggregator", | ||
| "pool": "Pool", | ||
| "clp": "CLP" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Potential duplicate explore.tags block – please verify
A tags object for the Explore page already existed in previous commits. Adding the same object again will silently override earlier keys at load time or, depending on the JSON loader, even break parsing.
Please confirm there is only a single "tags" object under "explore" in the final file.
If multiple occurrences appear, remove the redundant block or merge the entries.
🏁 Script executed:
#!/bin/bash
# Show all occurrences of "explore.tags" to detect duplicates
rg -n '"explore"\s*:\s*\{' -A15 src/assets/translations/en/main.json | grep -n '"tags"' -C2Length of output: 93
🏁 Script executed:
#!/bin/bash
# Locate every "explore" key and list any "tags" entries within the next 30 lines
rg -n '"explore"' src/assets/translations/en/main.json | cut -d: -f1 | while read -r ln; do
echo "→ explore block at line $ln:"
sed -n "${ln},$((ln+30))p" src/assets/translations/en/main.json | grep -n '"tags"'
doneLength of output: 412
Consolidate explore translations into a single block
Our inspection shows two separate "explore" objects in src/assets/translations/en/main.json (at lines ~612 and ~2647), but only the second contains your new "tags" section. Having duplicate top-level keys will either override earlier entries or break parsing.
Please merge the new "tags" entries into the existing "explore" block (around line 612) and remove the redundant block at line 2647:
• File: src/assets/translations/en/main.json
– Existing explore block starts at ~612
– Redundant explore block (with "tags") starts at ~2647
Action items:
- Cut the
"tags": { … }object from the second block. - Paste it under the first
"explore"object. - Delete the now-empty second
"explore"block.
This will ensure there’s only one "explore" key and prevent silently dropped or overridden translations.
🤖 Prompt for AI Agents
In src/assets/translations/en/main.json around lines 612 and 2647, there are two
separate "explore" objects causing duplicate keys. To fix this, cut the "tags"
object from the second "explore" block at line 2647, paste it inside the first
"explore" block near line 612, and then delete the entire second "explore" block
to ensure only one consolidated "explore" key remains.
Description
Adds both the category page to show the full asset list and the portals tags slider
If you click on any sliders, it will use a different portals API call to filter assets, ordered by volume so the most used ones are on the top
Search input should work on the current asset list which is not 100% accurate as we might want to search on every portals assets but to avoid rate limiting it's quite convenient for now, assuming the best volume should be the most interesting assets
Issue (if applicable)
closes #10108
closes #10109
Risk
Low
Testing
Engineering
Operations
Screenshots (if applicable)
Summary by CodeRabbit
New Features
Enhancements
Bug Fixes