Skip to content

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Sep 2, 2025

Description

This PR:

  • Adds new nav and remove previous one on desktop
  • Adds a bunch of brand/assets
  • Makes the buy-crypto route ramp with /buy and /sell subroutes, so we can route to those separately
  • Gibs lil room to breathe to content so that it doesn't take all screen width now that we've removed the nav
  • Ensure swapper is properly on top of bg, without opacity and with correct z-index
  • Does many, many related style improvements related to this feature on desktop and mobile

It does not:

0. Fiat ramps
  - [x] make buy and sell separate subroutes
1. Main layout
  - [x] vibe base layout
  - [x] new brand assets
  - [x] more vibe 
  - [x] fix submenu styles (bg/hover states)
  - [x] add active styles for all 3 mains
  - [x] add active style for submenu 
  - [x] improve hover behaviour 
  - [ ] ensure content is nice and centered, there is no global content shift (or rather, there is an offset if needed as a result of new nav)
2. User menu 
   - [x] Implement new user menu styles
   - [x] User menu 
   - [x] User menu dropdown
3. WC 
  - [ ] Move WC to user menu and uncomment early return
4. Regression/test 
  - [x] All routes are happy 
  - [x] All selected/hover states are happy 
  - [x] Triple-check chevron down are present where they should be 
  - [x] Regression test all on desktop/mobile

Issue (if applicable)

closes #10284
closes #10421

Risk

High Risk PRs Require 2 approvals

Medium- huge surface area although mostly view-layer style thingies

What protocols, transaction types, wallets or contract interactions might be affected by this PR?

Testing

  • All links in the new nav are happy
  • All app routes content is happy on desktop and mobile (pay special attention to swapper and fiat ramps) - pay particular attention to no padding/margins being added on mobile against develop
  • Pay particular attention to Buy/Sell routing being happy, as well as buy/sell tabs working fiat ramps
  • Ensure that opening the app and going to a given asset (without going to fiat ramps first) does display the buy/sell button on the asset page (assuming you're connected)
  • No styles from the new nav radiate on mobile
  • Search is happy on desktop/mobile

Engineering

  • ^

Operations

  • 🏁 My feature is behind a flag and doesn't require operations testing (yet)

Screenshots (if applicable)

  • ^

https://jam.dev/c/927a40ee-c01b-4037-9cd3-ba85273a8006

Summary by CodeRabbit

  • New Features

    • Replaced Buy Crypto with a new Ramp page offering dedicated Buy and Sell flows at /ramp/buy and /ramp/sell.
    • Redesigned header with a ShapeShift menu and Trade / Explore / Earn dropdowns; global search centered.
    • Wallet menu: native wallets gain in-menu rename/delete actions.
    • Added OG and ShapeShift wordmark icons.
  • Style

    • Updated header/button variants, wallet button visuals, overlays, spacing, and responsive behaviors.
  • Localization

    • Moved Buy/Sell copy into ramp translations; updated navigation labels and added Tokens/Swap.
  • Chores

    • Sitemap updated to new Ramp URLs.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 2, 2025

📝 Walkthrough

Walkthrough

Routing and header redesigned: /buy-crypto replaced by /ramp/* with nested buy/sell routes and a new Ramp page; top navigation and ShapeShift menu added; Layout/Main restructured; translation keys migrated to rampPage; multiple UI, icon, and styling updates applied.

Changes

Cohort / File(s) Summary
Routing & Types
src/Routes/Routes.tsx, src/Routes/RoutesCommon.tsx, src/Routes/helpers.ts
Catch-all Layout now receives explicit props; /buy-crypto replaced by /ramp/* with nested /ramp/buy and /ramp/sell and asset-specific paths; dynamic import switched from BuyRamp; Route type gains optional fullWidth?: boolean; trade shortLabel key updated.
Ramp feature & Buy migration
src/pages/Ramp/Ramp.tsx, src/pages/Buy/Buy.tsx, src/pages/Buy/TopAssets.tsx, src/components/Modals/NativeOnboarding/components/EasyToUse.tsx, public/sitemap.txt
New Ramp page/component added; buy page translations switched to rampPage; onboarding link updated to /ramp/buy; sitemap entries updated to /ramp/buy and /ramp/sell.
Header & Top Navigation
src/components/Layout/Header/Header.tsx, src/components/Layout/Header/NavBar/NavigationDropdown.tsx, src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx, src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx, src/components/Layout/Header/NavBar/WalletButton.tsx, src/components/Layout/Header/NavBar/ChainMenu.tsx, src/components/Layout/Header/ActionCenter/ActionCenter.tsx, src/components/Layout/Header/NavBar/Native/NativeMenu.tsx, src/components/Layout/Header/NavBar/WalletConnectedMenu.tsx, src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx, src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx
SideNav replaced by top nav: added ShapeShiftMenu and NavigationDropdown components; center search repositioned; multiple buttons set to variant='ghost', size/hover/visibility adjustments; GlobalSeachButton renamed to GlobalSearchButton; WalletConnectedMenu adds native rename/delete actions; NativeMenu simplified.
Layout & Main
src/components/Layout/Layout.tsx, src/components/Layout/Main.tsx, src/components/Layout/Header/SideNav.tsx (deleted), src/components/Layout/Header/AppLoadingIcon.tsx (deleted)
Removed SideNav and AppLoadingIcon; Header moved outside Container into top-level column Flex; Container maxWidth and px handling refactored; Main gains pageProps?: FlexProps and isSubPage?: boolean.
Translations
src/assets/translations/en/main.json
buyPage replaced with rampPage (separate buy/sell keys plus shared fields); navBar.tradeShort removed; navBar.tokens and navBar.swap added; new shapeShiftMenu structure added.
Fiat Ramps UI/Modal
src/components/Modals/FiatRamps/components/FiatRampActionButtons.tsx, src/components/Modals/FiatRamps/views/Overview.tsx
Tab handlers now navigate to /ramp/buy or /ramp/sell before setting action; Overview syncs internal action with defaultAction via useEffect.
Prefetching
src/context/AppProvider/AppContext.tsx
Calls useGetFiatRampsQuery() on app load (result unused) to prefetch fiat ramps.
Trade visuals & overlays
src/pages/Trade/tabs/TradeTab.tsx, src/pages/Trade/tabs/LimitTab.tsx, src/pages/Trade/tabs/ClaimTab.tsx, src/pages/Trade/constants.ts, src/components/MultiHopTrade/components/SharedTradeInput/SharedTradeInput.tsx
Added gridOverlaySx and blurBackgroundSx constants; trade tab wrappers changed to Box using _before/_after overlays; multiple card background tokens at md breakpoint changed to darkNeutral.800.
Asset & Dashboard labels
src/components/AssetHeader/AssetActions.tsx, src/pages/Dashboard/components/DashboardHeader/DashboardHeaderTop.tsx
Replaced navBar.tradeShort translation usage with common.trade for button labels/aria-labels.
Icons
src/components/Icons/OGIcon.tsx, src/components/Icons/ShapeShiftLogoText.tsx
Added OGIcon and ShapeShiftLogoText Chakra icon components.
Small UX/UI tweaks
Various files (ActionCenter, ChainMenu, GlobalSearchButton, WalletButton, MultiHopTrade components, Cancel/Confirm/Limit/Quote components, Claim components, NewWalletViewsSwitch)
Button variant/size/hover adjustments (many to ghost), responsive breakpoint tweaks, modal overlay close behavior changed, presentational background token swaps, and minor signature updates (e.g., WalletButton props).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Router
  participant RampPage as Ramp
  participant API as FiatRamps API
  participant WalletModal as WalletModal

  User->>Router: Navigate to /ramp
  Router-->>Router: Redirect /ramp -> /ramp/buy
  Router->>RampPage: Render RampContent (Buy)
  RampPage->>API: useGetFiatRampsQuery()
  API-->>RampPage: Ramps data
  alt Wallet not connected
    RampPage->>User: Show "Connect Wallet" CTA
    User->>WalletModal: Click Connect Wallet
    WalletModal-->>User: Open wallet modal
  end
  User->>RampPage: Click "Sell" tab
  RampPage->>Router: navigate('/ramp/sell')
  Router->>RampPage: Render RampContent (Sell)
Loading
sequenceDiagram
  autonumber
  actor User
  participant Header
  participant NavDD as NavigationDropdown
  participant Router

  User->>Header: Hover "Trade"
  Header->>NavDD: open on hover
  NavDD-->>NavDD: compute isActive (path prefixes)
  User->>NavDD: Click "Buy/Sell"
  NavDD->>Router: navigate('/ramp/buy' or '/ramp/sell')
  Router-->>Header: update active state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

high risk

Suggested reviewers

  • NeOMakinG
  • premiumjibles

Pre-merge checks (3 passed, 2 warnings)

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The PR implements the top-navigation and submenu structure required by [#10284] (side nav → top nav, NavigationDropdowns, ShapeShiftMenu) and it adds ramp routes plus an AppContext prefetch of fiat ramps that addresses the Buy/Sell visibility issue in [#10421]; however the desktop footer/carousel feature set described in PROD-37 is explicitly not implemented in this PR (the diff/PR notes show no carousel or trending-list work). As a result, two linked issues (#10284 and #10421) are satisfied by the changes, while PROD-37 remains unaddressed. Resolve by either implementing the PROD-37 footer/carousel requirements in a follow-up PR or removing PROD-37 from this PR's linked issues and clearly documenting that scope decision; additionally add (or point reviewers to) tests or manual verification steps that confirm buy/sell visibility on asset pages and document the AppContext prefetch to help reviewers validate no regressions.
Out of Scope Changes Check ⚠️ Warning Most UI and routing changes align with the nav redesign, but there are notable out-of-scope or risky changes in this diff: WalletButtonProps' public API was changed (new isConnected, isLoadingLocalWallet, onConnect props) which is a breaking surface and requires verification across all callers, AppLoadingIcon was removed entirely, and numerous styling/token swaps across unrelated components increase the change surface. These API and large-surface cosmetic changes should be flagged for tighter review or isolated into separate PRs to reduce risk. Recommendation: revert or isolate the WalletButton public-API change until all call sites are updated and typechecked, confirm and document intentional deletions (AppLoadingIcon/SideNav), and move broad styling/token updates into separate, smaller PRs with visual-regression checks so reviewers can validate functional vs. cosmetic changes independently.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat: new nav" is concise and directly reflects the primary change (introducing a new navigation/top-nav), so it accurately summarizes the main intent of the PR while remaining short and scannable.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

I hop to new routes, top nav in sight,
Carrots and foxes gleam in the light.
Buy and sell now live on the ramp,
I twitch my whiskers, give a stamp.
New logos shine — a rabbit’s delight! 🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat_new_nav

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

❤️ Share

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

@gomesalexandre gomesalexandre changed the title feat: vibe feat: new nav Sep 2, 2025
@twblack88
Copy link
Contributor

Gomes naming conventions continue to be the best vibez

gomesalexandre and others added 11 commits September 3, 2025 09:37
- Update dropdown background to use glassy/translucent effect with blur
- Fix dropdown colors for better contrast (whiteAlpha variants)
- Add chevron down icon next to ShapeShift logo
- Update trade menu icons to better match design mocks:
  - Swap: refresh/circular arrows icon
  - Limit: histogram chart icon
  - Buy: credit card icon
  - Sell: simple arrow icon

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add vertical divider between action center and user menu for better visual separation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add rename (pencil) and delete (trash) icons next to Native Wallet name
- Move rename/delete functionality from menu items to header icons
- Remove rename/delete menu items from NativeMenu
- Clean up UserMenu border styling
- Style icons with proper circular backgrounds (gray and red)
- Icons positioned correctly but click functionality needs debugging

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add useLocation hook and isActive logic for Trade dropdown
- Implement active state detection for /trade, /limit, /claim, /buy-crypto routes
- Fix styling by using unstyled MenuButton with inner Box for text styling
- Navigation clicks and active state styling both working

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Update route path from /buy-crypto to /ramp in all files
- Keep translation keys and UI labels unchanged
- Update navigation active state logic for new route
- Update external widget redirect URLs

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add Ramp component with buy/sell subroutes
- Update navigation to use /ramp/buy and /ramp/sell
- Make FiatRampActionButtons navigate on ramp page, use state in modal
- Sync Overview state with URL-driven props

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Move useGetFiatRampsQuery to AppContext for centralized loading and update components to use selector instead of direct hook calls.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
gomesalexandre and others added 3 commits September 3, 2025 12:46
Add selected styles for submenu items and fix assets routing to /assets instead of /explore.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fix all ESLint issues:
- Remove unused imports and variables
- Wrap style objects in useMemo for performance
- Add useCallback for event handlers
- Fix parsing errors and clean up component structure

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Update FOX Token navigation link from /fox to /fox-ecosystem to align with develop branch routing.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
gomesalexandre and others added 3 commits September 3, 2025 13:12
- Replace tradeShort with common.trade across components
- Use existing translation keys: limitOrder.heading, fiatRamps.buy/sell, defi.earn
- Remove duplicate translation keys from en/main.json
- Keep navBar.tokens for explore menu

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
gomesalexandre and others added 2 commits September 3, 2025 14:04
- Move onClick to MenuButton to fix broken navigation
- Fix initial hover state bug by separating MenuButton from ReactRouterLink

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (9)
src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx (2)

58-62: Add focus-visible styling for keyboard users (optional)

Since you override bg/border on hover, explicitly ensuring a strong focus-visible state helps a11y.

         <Button
           width='full'
           leftIcon={searchIcon}
           onClick={onOpen}
           size='md'
           fontSize='sm'
           alignItems='center'
           color='text.subtle'
           display={displayProp2}
           sx={sxProp1}
           bg='background.surface.base'
           border='1px solid'
           borderColor='border.base'
           _hover={buttonHoverSx}
+          _focusVisible={{ boxShadow: 'outline' }}
         >

42-47: Expose expanded/haspopup state for the modal trigger (optional)

The triggers open a modal; advertise this to AT users.

         <IconButton
           display={displayProp1}
           icon={searchIcon}
           aria-label={translate('common.search')}
+          aria-haspopup='dialog'
+          aria-expanded={isOpen}
           onClick={onOpen}
         />
         <Button
           width='full'
           leftIcon={searchIcon}
           onClick={onOpen}
           size='md'
           fontSize='sm'
           alignItems='center'
           color='text.subtle'
           display={displayProp2}
           sx={sxProp1}
           bg='background.surface.base'
           border='1px solid'
           borderColor='border.base'
           _hover={buttonHoverSx}
+          aria-haspopup='dialog'
+          aria-expanded={isOpen}
         >

Also applies to: 49-62

src/components/Layout/Header/NavBar/WalletButton.tsx (1)

95-106: Menu button a11y hint (optional)

When rendered inside a Menu, adding haspopup/expanded improves AT hints without impacting visuals.

     <ButtonComp
       as={Button}
       width={widthProp}
       justifyContent='flex-start'
       rightIcon={rightIcon}
       leftIcon={leftIcon}
       onClick={handleMenuClick}
       size='md'
       fontSize='sm'
       variant='ghost'
       bg='transparent'
+      aria-haspopup={isMenuContext ? 'menu' : undefined}
+      aria-expanded={isMenuContext ? true : undefined}
       {...otherProps}
     >
src/components/Layout/Header/Header.tsx (1)

113-121: Avoid potential horizontal overflow from width + margin combo (optional)

Using width='98%' with margin='4' can exceed the container width in narrow layouts and cause subtle horizontal scroll. Prefer full width + horizontal padding or a maxW-centered container.

       <Flex
         direction='column'
-        width='98%'
+        width='full'
         position='sticky'
         zIndex='banner'
         ref={ref}
         bg={y > height ? 'background.surface.base' : 'gray.950'}
         border='1px solid'
         borderColor='border.base'
         borderRadius='lg'
-        margin='4'
+        px={4}
+        py={4}
+        mx='auto'
+        maxW='8xl'
         transitionDuration='200ms'
src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx (3)

37-43: Ensure ellipsis actually applies

For textOverflow='ellipsis' to work, add whiteSpace='nowrap' (or switch to Text/RawText with noOfLines={1}).

-          {isLargerThanXl && (
-            <Box overflow='hidden' textOverflow='ellipsis'>
+          {isLargerThanXl && (
+            <Box overflow='hidden' textOverflow='ellipsis' whiteSpace='nowrap'>

3-3: SSR-safe media query (optional)

If this view can render on the server, consider Chakra’s SSR option or useBreakpointValue to avoid hydration flicker.

-  const [isLargerThanXl] = useMediaQuery(`(min-width: ${breakpoints['xl']})`)
+  const [isLargerThanXl] = useMediaQuery(`(min-width: ${breakpoints['xl']})`, { ssr: true, fallback: false })

If the app is strictly client-rendered, you can ignore this.

Also applies to: 11-11, 20-20


16-16: Optional: memoize component

This component receives props; wrapping with memo aligns with the project’s pattern in adjacent header components.

-export const WalletConnectButtons = (buttonProps?: ButtonProps) => {
+import { memo } from 'react'
+export const WalletConnectButtons = memo((buttonProps?: ButtonProps) => {
   ...
-}
+})
src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx (2)

32-36: Guarantee single-line truncation

Use Chakra’s noOfLines={1} to ensure ellipsis without relying on multiple style props.

-      <RawText pr={paddingProp} fontSize='sm' overflow='hidden' textOverflow='ellipsis'>
+      <RawText pr={paddingProp} fontSize='sm' noOfLines={1}>
         {title}
       </RawText>
-      <RawText fontSize='xs' color='text.subtle' overflow='hidden' textOverflow='ellipsis'>
+      <RawText fontSize='xs' color='text.subtle' noOfLines={1}>
         {subTitle}
       </RawText>

2-2: SSR-safe media query (optional)

Same note as the sibling component: consider the SSR option to prevent hydration mismatch if server-rendered.

-  const [isLargerThanXl] = useMediaQuery(`(min-width: ${breakpoints['xl']})`)
+  const [isLargerThanXl] = useMediaQuery(`(min-width: ${breakpoints['xl']})`, { ssr: true, fallback: false })

Also applies to: 17-17, 45-45

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b1edc7d and d436ec6.

📒 Files selected for processing (6)
  • src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx (2 hunks)
  • src/components/Layout/Header/Header.tsx (4 hunks)
  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx (1 hunks)
  • src/components/Layout/Header/NavBar/WalletButton.tsx (3 hunks)
  • src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx (3 hunks)
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
🧰 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/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx
  • src/components/Layout/Header/NavBar/WalletButton.tsx
  • src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx
  • src/components/Layout/Header/Header.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/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx
  • src/components/Layout/Header/NavBar/WalletButton.tsx
  • src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx
  • src/components/Layout/Header/Header.tsx
**/*

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*: ALWAYS use appropriate file extensions
Flag files without kebab-case

Files:

  • src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx
  • src/components/Layout/Header/NavBar/WalletButton.tsx
  • src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx
  • src/components/Layout/Header/Header.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

**/*.{tsx,jsx}: ALWAYS use useMemo for expensive computations, object/array creations, and filtered data
ALWAYS use useMemo for derived values and computed properties
ALWAYS use useMemo for conditional values and simple transformations
ALWAYS use useCallback for event handlers and functions passed as props
ALWAYS use useCallback for any function that could be passed as a prop or dependency
ALWAYS include all dependencies in useEffect, useMemo, useCallback dependency arrays
NEVER use // eslint-disable-next-line react-hooks/exhaustive-deps unless 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 with memo

Files:

  • src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx
  • src/components/Layout/Header/NavBar/WalletButton.tsx
  • src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx
  • src/components/Layout/Header/Header.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/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx
  • src/components/Layout/Header/NavBar/WalletButton.tsx
  • src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx
  • src/components/Layout/Header/Header.tsx
🧠 Learnings (7)
📓 Common learnings
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
PR: shapeshift/web#10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
PR: shapeshift/web#10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
Learnt from: gomesalexandre
PR: shapeshift/web#10418
File: src/Routes/RoutesCommon.tsx:231-267
Timestamp: 2025-09-03T21:17:27.681Z
Learning: gomesalexandre prefers to keep PR diffs focused and reasonable in size, deferring tangential improvements (like Mixpanel privacy enhancements) to separate efforts rather than expanding the scope of feature PRs.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpActionSubscriber.tsx:46-53
Timestamp: 2025-08-14T19:21:45.426Z
Learning: gomesalexandre does not like code patterns being labeled as "technical debt" and prefers neutral language when discussing existing code patterns that were intentionally moved/maintained for consistency.
📚 Learning: 2025-08-08T14:59:40.422Z
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/pages/Explore/ExploreCategory.tsx:231-238
Timestamp: 2025-08-08T14:59:40.422Z
Learning: In src/pages/Explore/ExploreCategory.tsx, for the PageHeader filter trigger, NeOMakinG considers changing a clickable Chakra Icon to IconButton too nitpicky for this PR and prefers to keep the current Icon-based trigger; such minor a11y/UI nitpicks should be deferred to a follow-up if needed.

Applied to files:

  • src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx
  • src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx
  • src/components/Layout/Header/Header.tsx
📚 Learning: 2025-08-08T15:00:49.887Z
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.

Applied to files:

  • src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/components/Layout/Header/Header.tsx
📚 Learning: 2025-08-08T15:00:22.321Z
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/components/MultiHopTrade/components/TradeInput/components/HighlightedTokens.tsx:14-14
Timestamp: 2025-08-08T15:00:22.321Z
Learning: In shapeshift/web reviews for NeOMakinG, avoid nitpicks to change deep-relative imports to '@/…' alias paths within feature/non-refactor PRs; defer such style-only changes to a dedicated follow-up refactor unless they fix an issue.

Applied to files:

  • src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/components/Layout/Header/Header.tsx
📚 Learning: 2025-08-27T09:47:06.275Z
Learnt from: NeOMakinG
PR: shapeshift/web#10323
File: src/components/ButtonWalletPredicate/ButtonWalletPredicate.tsx:7-7
Timestamp: 2025-08-27T09:47:06.275Z
Learning: In shapeshift/web project, NeOMakinG consistently prefers to defer UI/UX improvements and refactoring work (like the Drawer.Close hack fix in ButtonWalletPredicate.tsx) to follow-up PRs rather than expanding the scope of feature PRs, even when the improvements would enhance robustness.

Applied to files:

  • src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx
  • src/components/Layout/Header/Header.tsx
📚 Learning: 2025-09-04T12:16:47.728Z
Learnt from: gomesalexandre
PR: shapeshift/web#10430
File: src/components/Layout/Header/NavBar/PopoverWallet.tsx:72-94
Timestamp: 2025-09-04T12:16:47.728Z
Learning: gomesalexandre declined to add error boundaries to the PopoverWallet component in src/components/Layout/Header/NavBar/PopoverWallet.tsx, stating he didn't touch this component and preferring not to expand the scope of the PR with error boundary additions.

Applied to files:

  • src/components/Layout/Header/NavBar/WalletButton.tsx
  • src/components/Layout/Header/Header.tsx
📚 Learning: 2025-08-22T12:59:01.210Z
Learnt from: NeOMakinG
PR: shapeshift/web#10323
File: src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx:26-29
Timestamp: 2025-08-22T12:59:01.210Z
Learning: In src/components/Layout/Header/ActionCenter/components/RewardDistributionActionCard.tsx, NeOMakinG declined wrapping the RewardDistributionActionCard component with React.memo, saying it was "too much", suggesting that like other action center components, memoization is not beneficial for this specific use case.

Applied to files:

  • src/components/Layout/Header/Header.tsx
🧬 Code graph analysis (4)
src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx (1)
src/theme/theme.tsx (1)
  • breakpoints (37-44)
src/components/Layout/Header/NavBar/WalletButton.tsx (1)
src/components/Text/Text.tsx (1)
  • RawText (15-17)
src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx (1)
src/theme/theme.tsx (1)
  • breakpoints (37-44)
src/components/Layout/Header/Header.tsx (10)
src/state/slices/portfolioSlice/selectors.ts (1)
  • selectPortfolioDegradedState (183-188)
src/theme/theme.tsx (1)
  • breakpoints (37-44)
src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx (1)
  • ShapeShiftMenu (126-243)
src/components/Layout/Header/NavBar/NavigationDropdown.tsx (1)
  • NavigationDropdown (34-133)
src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx (1)
  • GlobalSearchButton (18-76)
src/components/Layout/Header/DegradedStateBanner.tsx (1)
  • DegradedStateBanner (39-185)
src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx (1)
  • WalletConnectToDappsHeaderButton (115-136)
src/components/Layout/Header/TxWindow/TxWindow.tsx (1)
  • TxWindow (62-152)
src/components/Layout/Header/NavBar/WalletManagerPopover.tsx (1)
  • WalletManagerPopover (11-52)
src/components/Layout/Header/NavBar/UserMenu.tsx (1)
  • UserMenu (62-113)
⏰ 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 (12)
src/components/Layout/Header/GlobalSearch/GlobalSearchButton.tsx (2)

22-28: Good use of memoized hover styles

Extracting hover styles via useMemo avoids re-creating objects on each render and keeps Chakra’s style diffing lean.


52-53: Consistent sizing choices

Aligning size='md' and fontSize='sm' with the new header scale looks good.

src/components/Layout/Header/NavBar/WalletButton.tsx (3)

23-23: Unified hover token for connect button

Centralizing hover styles improves consistency across header controls.


25-31: Prop API looks solid

Explicit isConnected/isLoadingLocalWallet/onConnect props make state handling clear and avoid implicit coupling to context.


117-126: Connect button styling LGTM

Clear call-to-action with consistent sizing and hover behavior.

src/components/Layout/Header/Header.tsx (3)

47-63: Nav submenu data reads well

Routes and i18n labels map cleanly; icons communicate intent. No concerns.


146-149: Center search box behavior LGTM

Responsive flex/maxW settings keep search discoverable without crowding nav/actions.


150-167: Right-side controls: good feature-flagging and fallbacks

Conditional rendering for degraded state, WalletConnect, TxWindow/ActionCenter, and wallet manager is clean and discrete.

src/plugins/walletConnectToDapps/components/header/ConnectDapp.tsx (1)

30-36: Confirm prop override intent

rightIcon/leftIcon/variant can be overridden by buttonProps since spread comes last. Confirm this is desired.

src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx (3)

55-58: LGTM on rightIcon memoization

Good use of useMemo to avoid recreating icons per render.


42-77: Efficient sessions derivation

Filtering to sessions and memoizing leftIcon AvatarGroup by sessions is solid and avoids unnecessary renders.


130-135: Conditional rendering path looks correct

Switch handling between connect vs connected states aligns with feature flags and session presence.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx (1)

148-162: MenuButton as HStack: prior a11y suggestion acknowledged.

Previously suggested converting the trigger to a real Button for keyboard semantics and adding an aria-label. Author declined; not blocking here.

🧹 Nitpick comments (2)
src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx (2)

164-173: Guard against small viewports to avoid overflow.

If this renders on narrower layouts (or in responsive testing tools), minW='500px' can overflow. Cap width to viewport.

Apply this diff:

-          minW='500px'
+          minW='500px'
+          maxW='95vw'

181-208: DRY up product items with a typed config array (optional).

Mapping over a config reduces duplication and eases future additions.

I can provide a follow-up refactor if desired.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d436ec6 and 510002c.

📒 Files selected for processing (2)
  • src/components/Layout/Header/NavBar/NavigationDropdown.tsx (1 hunks)
  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Layout/Header/NavBar/NavigationDropdown.tsx
🧰 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/components/Layout/Header/NavBar/ShapeShiftMenu.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/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
**/*

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*: ALWAYS use appropriate file extensions
Flag files without kebab-case

Files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

**/*.{tsx,jsx}: ALWAYS use useMemo for expensive computations, object/array creations, and filtered data
ALWAYS use useMemo for derived values and computed properties
ALWAYS use useMemo for conditional values and simple transformations
ALWAYS use useCallback for event handlers and functions passed as props
ALWAYS use useCallback for any function that could be passed as a prop or dependency
ALWAYS include all dependencies in useEffect, useMemo, useCallback dependency arrays
NEVER use // eslint-disable-next-line react-hooks/exhaustive-deps unless 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 with memo

Files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.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/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
🧠 Learnings (11)
📓 Common learnings
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
PR: shapeshift/web#10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
PR: shapeshift/web#10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
Learnt from: gomesalexandre
PR: shapeshift/web#10418
File: src/Routes/RoutesCommon.tsx:231-267
Timestamp: 2025-09-03T21:17:27.681Z
Learning: gomesalexandre prefers to keep PR diffs focused and reasonable in size, deferring tangential improvements (like Mixpanel privacy enhancements) to separate efforts rather than expanding the scope of feature PRs.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpActionSubscriber.tsx:46-53
Timestamp: 2025-08-14T19:21:45.426Z
Learning: gomesalexandre does not like code patterns being labeled as "technical debt" and prefers neutral language when discussing existing code patterns that were intentionally moved/maintained for consistency.
📚 Learning: 2025-08-08T14:59:40.422Z
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/pages/Explore/ExploreCategory.tsx:231-238
Timestamp: 2025-08-08T14:59:40.422Z
Learning: In src/pages/Explore/ExploreCategory.tsx, for the PageHeader filter trigger, NeOMakinG considers changing a clickable Chakra Icon to IconButton too nitpicky for this PR and prefers to keep the current Icon-based trigger; such minor a11y/UI nitpicks should be deferred to a follow-up if needed.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-08-08T15:00:49.887Z
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-08-25T23:32:13.876Z
Learnt from: premiumjibles
PR: shapeshift/web#10361
File: src/pages/Markets/components/CardWithSparkline.tsx:83-92
Timestamp: 2025-08-25T23:32:13.876Z
Learning: In shapeshift/web PR #10361, premiumjibles considered the nested button accessibility issue (ChartErrorFallback retry Button inside Card rendered as Button in CardWithSparkline.tsx) out of scope for the error boundaries feature PR, consistent with deferring minor a11y improvements to follow-up PRs.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-09-03T20:56:35.789Z
Learnt from: gomesalexandre
PR: shapeshift/web#10418
File: src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx:1-15
Timestamp: 2025-09-03T20:56:35.789Z
Learning: gomesalexandre dismisses accessibility improvements with "meh accessibility", preferring to keep existing implementations over making elements properly accessible in feature PRs.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-08-27T09:47:06.275Z
Learnt from: NeOMakinG
PR: shapeshift/web#10323
File: src/components/ButtonWalletPredicate/ButtonWalletPredicate.tsx:7-7
Timestamp: 2025-08-27T09:47:06.275Z
Learning: In shapeshift/web project, NeOMakinG consistently prefers to defer UI/UX improvements and refactoring work (like the Drawer.Close hack fix in ButtonWalletPredicate.tsx) to follow-up PRs rather than expanding the scope of feature PRs, even when the improvements would enhance robustness.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-08-08T15:00:22.321Z
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/components/MultiHopTrade/components/TradeInput/components/HighlightedTokens.tsx:14-14
Timestamp: 2025-08-08T15:00:22.321Z
Learning: In shapeshift/web reviews for NeOMakinG, avoid nitpicks to change deep-relative imports to '@/…' alias paths within feature/non-refactor PRs; defer such style-only changes to a dedicated follow-up refactor unless they fix an issue.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-09-03T21:17:27.681Z
Learnt from: gomesalexandre
PR: shapeshift/web#10418
File: src/Routes/RoutesCommon.tsx:231-267
Timestamp: 2025-09-03T21:17:27.681Z
Learning: gomesalexandre prefers to keep PR diffs focused and reasonable in size, deferring tangential improvements (like Mixpanel privacy enhancements) to separate efforts rather than expanding the scope of feature PRs.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-09-04T12:16:47.728Z
Learnt from: gomesalexandre
PR: shapeshift/web#10430
File: src/components/Layout/Header/NavBar/PopoverWallet.tsx:72-94
Timestamp: 2025-09-04T12:16:47.728Z
Learning: gomesalexandre declined to add error boundaries to the PopoverWallet component in src/components/Layout/Header/NavBar/PopoverWallet.tsx, stating he didn't touch this component and preferring not to expand the scope of the PR with error boundary additions.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-09-02T12:38:46.940Z
Learnt from: NeOMakinG
PR: shapeshift/web#10380
File: src/components/Table/Table.theme.ts:177-180
Timestamp: 2025-09-02T12:38:46.940Z
Learning: NeOMakinG prefers to defer technical debt and CSS correctness issues (like improper hover selectors) to follow-up PRs when the current PR is already large and focused on major feature implementation, even when the issues are valid from a usability/technical perspective.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
📚 Learning: 2025-08-25T12:59:43.842Z
Learnt from: NeOMakinG
PR: shapeshift/web#10323
File: src/pages/Fox/components/RFOXSection.tsx:234-248
Timestamp: 2025-08-25T12:59:43.842Z
Learning: NeOMakinG considers suggestions to refactor working modal state management from useState to useDisclosure as too nitpicky, preferring to keep such cosmetic code improvements out of feature PRs unless they address actual issues.

Applied to files:

  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
🧬 Code graph analysis (1)
src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx (3)
src/theme/theme.tsx (1)
  • breakpoints (37-44)
src/components/Icons/ShapeShiftLogoText.tsx (1)
  • ShapeShiftLogoText (3-64)
src/components/Icons/OGIcon.tsx (1)
  • OGIcon (3-43)
⏰ 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/components/Layout/Header/NavBar/ShapeShiftMenu.tsx (1)

189-193: Route exists — no changes required.

src/Routes/RoutesCommon.tsx defines path '/fox-ecosystem/*' (≈line 311). The menu href uses '/fox-ecosystem' (src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx:192) and several navigate() calls point to it (e.g. src/pages/RFOX/components/ClaimModal.tsx:34, src/pages/Explore/Explore.tsx:127, src/components/Layout/Header/ActionCenter/components/RfoxClaimActionCard.tsx:42).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx (2)

138-156: Fix stale memo: confirmCopy depends on reactive fields not in deps.

confirmCopy won’t update when isError toggles because the objects are stable. Add the specific primitives (and used asset fields) to deps.

Apply:

-  const confirmCopy = useMemo(() => {
+  const confirmCopy = useMemo(() => {
     if (claimMutation.isError) {
       return translate('trade.errors.title')
     }
     if (evmFeesResult.isError) {
-      console.error(evmFeesResult.error)
+      console.error(evmFeesResult.error)
       return translate('trade.errors.networkFeeEstimateFailed')
     }
     if (!hasEnoughDestinationFeeBalance) {
       return translate('common.insufficientAmountForGas', {
         assetSymbol: destinationFeeAsset?.symbol,
         chainSymbol: getChainShortName(destinationFeeAsset?.chainId as KnownChainIds),
       })
     }
     return translate('bridge.confirmAndClaim')
-  }, [claimMutation, destinationFeeAsset, evmFeesResult, hasEnoughDestinationFeeBalance, translate])
+  }, [
+    claimMutation.isError,
+    evmFeesResult.isError,
+    hasEnoughDestinationFeeBalance,
+    destinationFeeAsset?.chainId,
+    destinationFeeAsset?.symbol,
+    translate,
+  ])

124-131: Guard possible undefined balance before toBaseUnit().

If destinationFeeAssetBalanceCryptoPrecision can be undefined, toBaseUnit may throw. Default to '0'.

-    return bnOrZero(evmFeesResult.data.networkFeeCryptoBaseUnit).lte(
-      toBaseUnit(destinationFeeAssetBalanceCryptoPrecision, destinationFeeAsset.precision),
-    )
+    return bnOrZero(evmFeesResult.data.networkFeeCryptoBaseUnit).lte(
+      toBaseUnit(destinationFeeAssetBalanceCryptoPrecision ?? '0', destinationFeeAsset.precision),
+    )
src/components/MultiHopTrade/components/QuoteList/QuoteList.tsx (1)

86-94: Add key prop to mapped MenuItemOption elements.

Prevents React key warnings and improves list diffing.

-                {quoteSortOptions.map(quoteSortOpt => (
-                  <MenuItemOption
-                    value={quoteSortOpt.value}
+                {quoteSortOptions.map(quoteSortOpt => (
+                  <MenuItemOption
+                    key={quoteSortOpt.value}
+                    value={quoteSortOpt.value}
                     onClick={quoteSortOpt.handleClick}
                     fontSize='sm'
                   >
                     {quoteSortOpt.label}
                   </MenuItemOption>
                 ))}
🧹 Nitpick comments (5)
src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx (3)

211-216: Remove redundant nested Row.Value.

Avoid extra wrapper to keep DOM lean.

-              <Row.Value>
-                <Skeleton isLoaded={!evmFeesResult.isLoading && !evmFeesResult.isPending}>
-                  <Row.Value>
-                    <Amount.Fiat value={evmFeesResult?.data?.txFeeFiat || '0.00'} />
-                  </Row.Value>
-                </Skeleton>
-              </Row.Value>
+              <Row.Value>
+                <Skeleton isLoaded={!evmFeesResult.isLoading && !evmFeesResult.isPending}>
+                  <Amount.Fiat value={evmFeesResult?.data?.txFeeFiat || '0.00'} />
+                </Skeleton>
+              </Row.Value>

133-136: Handle mutateAsync errors and surface feedback.

Wrap in try/catch and show a translated toast; log via structured logging.

I can wire in useErrorToast and our logger if you want a quick patch.


144-145: Prefer structured logging over console.error.

Use the project logger with context (claim id, dest chain) to aid triage.

src/pages/Trade/constants.ts (2)

1-15: Consider typing and print-safety tweaks for overlays.

  • Narrow types and prevent accidental mutation with as const.
  • Hide overlays on print to avoid noisy printouts.
-export const gridOverlaySx = {
+export const gridOverlaySx = {
   content: '""',
   position: 'fixed' as const,
   top: '0',
   left: '0',
   right: '0',
   bottom: '0',
   backgroundImage:
     'linear-gradient(to right, rgba(255, 255, 255, 0.01) 1px, transparent 1px), linear-gradient(to bottom, rgba(255, 255, 255, 0.01) 1px, transparent 1px)',
   backgroundSize: '30px 30px',
   maskImage: 'linear-gradient(to bottom, white 0%, white 70%, transparent 100%)',
   WebkitMaskImage: 'linear-gradient(to bottom, white 0%, white 70%, transparent 100%)',
   zIndex: 1,
   pointerEvents: 'none' as const,
-}
+  '@media print': { display: 'none' },
+} as const

17-29: Same as above for blur overlay; minor perf safeguard.

Add print rule and finalize typing. Optionally reduce blur for low-power contexts later if needed.

-export const blurBackgroundSx = {
+export const blurBackgroundSx = {
   content: '""',
   position: 'fixed' as const,
   bottom: '0',
   left: '0',
   right: '0',
   height: '40vh',
   background:
     'radial-gradient(ellipse 150% 80% at 50% 100%, rgba(55, 97, 249, 1) 0%, rgba(55, 97, 249, 0.9) 20%, rgba(55, 97, 249, 0.4) 50%, rgba(55, 97, 249, 0) 80%), radial-gradient(ellipse 120% 70% at 20% 100%, rgba(165, 55, 249, 1) 0%, rgba(165, 55, 249, 0.8) 20%, rgba(165, 55, 249, 0.3) 50%, rgba(165, 55, 249, 0) 80%), radial-gradient(ellipse 100% 60% at 80% 100%, rgba(22, 209, 161, 0.6) 0%, rgba(22, 209, 161, 0.2) 40%, rgba(22, 209, 161, 0) 80%)',
   filter: 'blur(200px)',
   zIndex: 0,
   pointerEvents: 'none' as const,
-}
+  '@media print': { display: 'none' },
+} as const
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 510002c and 79decaa.

📒 Files selected for processing (15)
  • src/Routes/RoutesCommon.tsx (3 hunks)
  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx (1 hunks)
  • src/components/MultiHopTrade/components/LimitOrder/components/CancelLimitOrder.tsx (1 hunks)
  • src/components/MultiHopTrade/components/LimitOrder/components/LimitOrderConfirm.tsx (1 hunks)
  • src/components/MultiHopTrade/components/LimitOrder/components/LimitOrderList.tsx (1 hunks)
  • src/components/MultiHopTrade/components/QuoteList/QuoteList.tsx (1 hunks)
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx (1 hunks)
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirmFooter.tsx (1 hunks)
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/Claim.tsx (1 hunks)
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx (1 hunks)
  • src/pages/Trade/constants.ts (1 hunks)
  • src/pages/Trade/tabs/ClaimTab.tsx (3 hunks)
  • src/pages/Trade/tabs/LimitTab.tsx (3 hunks)
  • src/pages/Trade/tabs/TradeTab.tsx (3 hunks)
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx (5 hunks)
✅ Files skipped from review due to trivial changes (3)
  • src/components/MultiHopTrade/components/LimitOrder/components/LimitOrderList.tsx
  • src/components/MultiHopTrade/components/LimitOrder/components/LimitOrderConfirm.tsx
  • src/components/MultiHopTrade/components/LimitOrder/components/CancelLimitOrder.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/pages/Trade/tabs/TradeTab.tsx
  • src/components/Layout/Header/NavBar/ShapeShiftMenu.tsx
  • src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx
  • src/Routes/RoutesCommon.tsx
🧰 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/components/MultiHopTrade/components/SharedConfirm/SharedConfirmFooter.tsx
  • src/pages/Trade/constants.ts
  • src/components/MultiHopTrade/components/QuoteList/QuoteList.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/Claim.tsx
  • src/pages/Trade/tabs/ClaimTab.tsx
  • src/pages/Trade/tabs/LimitTab.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/components/MultiHopTrade/components/SharedConfirm/SharedConfirmFooter.tsx
  • src/components/MultiHopTrade/components/QuoteList/QuoteList.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/Claim.tsx
  • src/pages/Trade/tabs/ClaimTab.tsx
  • src/pages/Trade/tabs/LimitTab.tsx
**/*

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*: ALWAYS use appropriate file extensions
Flag files without kebab-case

Files:

  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirmFooter.tsx
  • src/pages/Trade/constants.ts
  • src/components/MultiHopTrade/components/QuoteList/QuoteList.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/Claim.tsx
  • src/pages/Trade/tabs/ClaimTab.tsx
  • src/pages/Trade/tabs/LimitTab.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

**/*.{tsx,jsx}: ALWAYS use useMemo for expensive computations, object/array creations, and filtered data
ALWAYS use useMemo for derived values and computed properties
ALWAYS use useMemo for conditional values and simple transformations
ALWAYS use useCallback for event handlers and functions passed as props
ALWAYS use useCallback for any function that could be passed as a prop or dependency
ALWAYS include all dependencies in useEffect, useMemo, useCallback dependency arrays
NEVER use // eslint-disable-next-line react-hooks/exhaustive-deps unless 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 with memo

Files:

  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirmFooter.tsx
  • src/components/MultiHopTrade/components/QuoteList/QuoteList.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/Claim.tsx
  • src/pages/Trade/tabs/ClaimTab.tsx
  • src/pages/Trade/tabs/LimitTab.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/components/MultiHopTrade/components/SharedConfirm/SharedConfirmFooter.tsx
  • src/pages/Trade/constants.ts
  • src/components/MultiHopTrade/components/QuoteList/QuoteList.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/Claim.tsx
  • src/pages/Trade/tabs/ClaimTab.tsx
  • src/pages/Trade/tabs/LimitTab.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: gomesalexandre
PR: shapeshift/web#10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:47.970Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR #10418 for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
PR: shapeshift/web#10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
PR: shapeshift/web#10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
Learnt from: gomesalexandre
PR: shapeshift/web#10418
File: src/Routes/RoutesCommon.tsx:231-267
Timestamp: 2025-09-03T21:17:27.681Z
Learning: gomesalexandre prefers to keep PR diffs focused and reasonable in size, deferring tangential improvements (like Mixpanel privacy enhancements) to separate efforts rather than expanding the scope of feature PRs.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpActionSubscriber.tsx:46-53
Timestamp: 2025-08-14T19:21:45.426Z
Learning: gomesalexandre does not like code patterns being labeled as "technical debt" and prefers neutral language when discussing existing code patterns that were intentionally moved/maintained for consistency.
📚 Learning: 2025-07-29T15:04:28.083Z
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/components/MultiHopTrade/components/QuoteList/QuoteList.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx
  • src/components/MultiHopTrade/components/TradeInput/components/Claim/Claim.tsx
📚 Learning: 2025-07-29T08:57:09.276Z
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/components/MultiHopTrade/components/QuoteList/QuoteList.tsx
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx
📚 Learning: 2025-08-08T11:41:36.971Z
Learnt from: NeOMakinG
PR: shapeshift/web#10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:88-109
Timestamp: 2025-08-08T11:41:36.971Z
Learning: In MultiHopTrade Confirm flow (src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx), the Confirm route does not remount; navigating away goes to the swapper input page. Therefore, persistent deduplication across remounts for quote tracking is unnecessary; a ref-based single-mount dedupe is sufficient.

Applied to files:

  • src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx
  • src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx
🧬 Code graph analysis (2)
src/pages/Trade/tabs/ClaimTab.tsx (1)
src/pages/Trade/constants.ts (2)
  • gridOverlaySx (1-15)
  • blurBackgroundSx (17-29)
src/pages/Trade/tabs/LimitTab.tsx (1)
src/pages/Trade/constants.ts (2)
  • gridOverlaySx (1-15)
  • blurBackgroundSx (17-29)
⏰ 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: Call / Static
🔇 Additional comments (7)
src/components/MultiHopTrade/components/TradeInput/components/Claim/ClaimConfirm.tsx (1)

49-49: Theming token change looks good.

bg at md → darkNeutral.800 aligns with the new palette.

src/components/MultiHopTrade/components/SharedConfirm/SharedConfirmFooter.tsx (1)

10-15: Footer background token change looks good.

Consistent with the md dark surface updates elsewhere.

src/components/MultiHopTrade/components/QuoteList/QuoteList.tsx (1)

38-38: Card bg token change looks good.

Keeps QuoteList aligned with the new md surface.

src/components/MultiHopTrade/components/TradeInput/components/Claim/Claim.tsx (1)

16-16: Card bg token change looks good.

Matches the shared md surface update.

src/pages/Trade/tabs/ClaimTab.tsx (1)

54-81: Overlay integration LGTM.

_box with fixed _before/_after + zIndex layering keeps content above visuals; SEO placement is fine.

src/components/MultiHopTrade/components/SharedConfirm/SharedConfirm.tsx (1)

19-41: SharedConfirm md bg token change looks good.

Consistent theming; no behavioral changes.

src/pages/Trade/tabs/LimitTab.tsx (1)

107-134: Overlay integration LGTM.

Consistent with Claim/Trade tabs; stacking and spacing read well.

@gomesalexandre gomesalexandre enabled auto-merge (squash) September 10, 2025 23:09
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (3)
src/assets/translations/en/main.json (1)

264-272: Ramp i18n keys look correct; minor copy nits for clarity/consistency.

  • Good rename and split into buy/sell copies.
  • Optional nits:
    • Add Oxford comma: “credit or debit card, or bank account”.
    • Align “Non-KYC” phrasing with existing “NO KYC” style under fiatRamps (or standardize to “No KYC required” across both).

Apply if you agree:

-    "buyBody": "Use a credit card, debit card or bank account. Buy Bitcoin, Ethereum, USDT, USDC or other top cryptocurrencies. Non-KYC providers available.",
+    "buyBody": "Use a credit or debit card, or bank account. Buy Bitcoin, Ethereum, USDT, USDC, or other top cryptocurrencies. No KYC required providers available.",
-    "sellBody": "Use a credit card, debit card or bank account. Sell Bitcoin, Ethereum, USDT, USDC or other top cryptocurrencies. Non-KYC providers available.",
+    "sellBody": "Use a credit or debit card, or bank account. Sell Bitcoin, Ethereum, USDT, USDC, or other top cryptocurrencies. No KYC required providers available.",

To ensure no lingering references to the old keys and the required interpolation var is provided:

#!/bin/bash
# 1) Check for old buyPage.* usages
rg -nP "\bbuyPage\."

# 2) Check for removed/old key usage navBar.tradeShort
rg -nP "\bnavBar\.tradeShort\b"

# 3) Confirm rampPage.ctaTitle usage supplies chainCount
rg -nP -C3 "translate\(['\"]rampPage\.ctaTitle['\"]" --type=ts --type=tsx

Note: English-only in this PR aligns with the repo’s two-step i18n workflow. No action needed on other locales now.

src/pages/Dashboard/components/DashboardHeader/DashboardHeaderTop.tsx (2)

157-161: Use of common.trade is correct and consistent with the key migration.

Swapping to translate('common.trade') removes dependency on the old nav key and keeps labels consistent across surfaces.


203-205: Desktop Trade label update LGTM.

Same reasoning as mobile: consistent with the translations refactor.

🧹 Nitpick comments (1)
src/assets/translations/en/main.json (1)

699-726: ShapeShift menu copy and structure LGTM; consider future-proofing “Twitter”.

Looks good. Optional: rename the label to “X (Twitter)” when product approves.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 79decaa and b71daf1.

📒 Files selected for processing (2)
  • src/assets/translations/en/main.json (3 hunks)
  • src/pages/Dashboard/components/DashboardHeader/DashboardHeaderTop.tsx (2 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/Dashboard/components/DashboardHeader/DashboardHeaderTop.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/Dashboard/components/DashboardHeader/DashboardHeaderTop.tsx
**/*

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*: ALWAYS use appropriate file extensions
Flag files without kebab-case

Files:

  • src/pages/Dashboard/components/DashboardHeader/DashboardHeaderTop.tsx
  • src/assets/translations/en/main.json
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

**/*.{tsx,jsx}: ALWAYS use useMemo for expensive computations, object/array creations, and filtered data
ALWAYS use useMemo for derived values and computed properties
ALWAYS use useMemo for conditional values and simple transformations
ALWAYS use useCallback for event handlers and functions passed as props
ALWAYS use useCallback for any function that could be passed as a prop or dependency
ALWAYS include all dependencies in useEffect, useMemo, useCallback dependency arrays
NEVER use // eslint-disable-next-line react-hooks/exhaustive-deps unless 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 with memo

Files:

  • src/pages/Dashboard/components/DashboardHeader/DashboardHeaderTop.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/Dashboard/components/DashboardHeader/DashboardHeaderTop.tsx
🧠 Learnings (2)
📓 Common learnings
Learnt from: gomesalexandre
PR: shapeshift/web#10418
File: src/plugins/walletConnectToDapps/components/header/WalletConnectToDappsHeaderButton.tsx:0-0
Timestamp: 2025-09-08T22:00:48.005Z
Learning: gomesalexandre dismissed an aria-label accessibility suggestion with "meh" in PR #10418 for WalletConnectToDappsHeaderButton.tsx, consistent with the team's pattern of deferring minor a11y improvements to follow-up PRs rather than expanding feature PR scope.
Learnt from: NeOMakinG
PR: shapeshift/web#10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
PR: shapeshift/web#10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
PR: shapeshift/web#10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
PR: shapeshift/web#10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
Learnt from: gomesalexandre
PR: shapeshift/web#10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.
Learnt from: gomesalexandre
PR: shapeshift/web#10418
File: src/Routes/RoutesCommon.tsx:231-267
Timestamp: 2025-09-03T21:17:27.699Z
Learning: gomesalexandre prefers to keep PR diffs focused and reasonable in size, deferring tangential improvements (like Mixpanel privacy enhancements) to separate efforts rather than expanding the scope of feature PRs.
Learnt from: gomesalexandre
PR: shapeshift/web#10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpActionSubscriber.tsx:46-53
Timestamp: 2025-08-14T19:21:45.426Z
Learning: gomesalexandre does not like code patterns being labeled as "technical debt" and prefers neutral language when discussing existing code patterns that were intentionally moved/maintained for consistency.
📚 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
⏰ 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: Call / Static
🔇 Additional comments (1)
src/assets/translations/en/main.json (1)

674-676: New nav labels LGTM.

navBar.tokens and navBar.swap additions are straightforward and consistent with the new top nav.

@gomesalexandre gomesalexandre merged commit 1e43636 into develop Sep 10, 2025
4 checks passed
@gomesalexandre gomesalexandre deleted the feat_new_nav branch September 10, 2025 23:14
0xApotheosis added a commit that referenced this pull request Sep 11, 2025
premiumjibles pushed a commit that referenced this pull request Sep 11, 2025
* Revert "feat: new nav (#10418)"

This reverts commit 1e43636.

* Revert "chore: enable new wallet manager (#10482)"

This reverts commit aa3b25a.
0xApotheosis added a commit that referenced this pull request Sep 11, 2025
* Revert "feat: new nav (#10418)"

This reverts commit 1e43636.

* Revert "chore: enable new wallet manager (#10482)"

This reverts commit aa3b25a.
@gomesalexandre gomesalexandre restored the feat_new_nav branch September 11, 2025 08:01
@coderabbitai coderabbitai bot mentioned this pull request Sep 11, 2025
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Buy/Sell button not displayed on asset page Implement top nav menu routes

4 participants