Skip to content

feat/PRO-3225/new-token-tiles#290

Merged
RanaBug merged 7 commits intostagingfrom
feat/PRO-3225/new-token-tiles
Apr 24, 2025
Merged

feat/PRO-3225/new-token-tiles#290
RanaBug merged 7 commits intostagingfrom
feat/PRO-3225/new-token-tiles

Conversation

@RanaBug
Copy link
Collaborator

@RanaBug RanaBug commented Apr 23, 2025

Description

  • New Token Tiles design and FE implementation

How Has This Been Tested?

  • Unit tests and manual testing

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Summary by CodeRabbit

  • New Features

    • Introduced a tile for displaying token market data, including token rows with detailed price, volume, liquidity, and transaction metrics.
    • Added components for rendering token logos (with blockchain overlays), customizable tile titles with optional decorators, and formatted timestamps with shortened time units.
    • Enabled navigation from token rows when links are provided.
    • Added visual indicators for price direction with colored icons and percentage changes.
  • Style

    • Added a new green color to the theme for market data highlights.
  • Bug Fixes

    • Improved image fallback handling for token and chain logos to prevent broken images.
  • Tests

    • Added comprehensive tests for token market data row components and the overall market data tile, ensuring correct rendering and edge case handling.

@RanaBug RanaBug requested a review from IAmKio April 23, 2025 13:35
@RanaBug RanaBug self-assigned this Apr 23, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 23, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap is excluded by !**/*.snap

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

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

Walkthrough

This update introduces a new "Tokens With Market Data" tile feature to the codebase. It adds several new React components for rendering token market data rows, including specialized components for left and right columns and token logos with fallback and overlay logic. The tile is integrated into the component mapping and type system, with new types and enum values defined to support structured token market data. Supporting utility functions and Tailwind color configuration are also added. Comprehensive tests accompany each new component to verify rendering and edge cases.

Changes

File(s) Change Summary
src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx New React component rendering the left column of a token market data row, formatting timestamps and handling copy-to-clipboard functionality.
src/apps/pillarx-app/components/TokenMarketDataRow/RightColumnTokenMarketDataRow.tsx New React component rendering the right column of a token market data row, showing price, direction, percentage, and transaction count with conditional styling.
src/apps/pillarx-app/components/TokenMarketDataRow/TokenLogoMarketDataRow.tsx New React component for rendering a token logo with optional blockchain logo overlay and fallback avatar logic for broken or missing images.
src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx New React component composing a full token market data row, integrating logo, left, and right column components, and handling navigation and styling.
src/apps/pillarx-app/components/TokenMarketDataRow/tests/LeftColumnTokenMarketDataRow.test.tsx
src/apps/pillarx-app/components/TokenMarketDataRow/tests/RightColumnTokenMarketDataRow.test.tsx
New test suites for the left and right column token market data row components, covering rendering, content, and edge cases.
src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx New React component rendering a tile of token market data, splitting rows for desktop layout and composing with row components.
src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx New test suite for the TokensWithMarketDataTile component, verifying rendering, decorators, row limits, and loading/empty states.
src/apps/pillarx-app/components/TileTitle/TileTitle.tsx New React component for rendering a tile title with optional left and right decorator images, including error handling for broken images.
src/apps/pillarx-app/tailwind.pillarx.config.js Added new color market_row_green to the extended Tailwind color palette.
src/apps/pillarx-app/utils/configComponent.ts Integrated the new TokensWithMarketDataTile component into the component mapping for the TOKENS_WITH_MARKET_DATA layout type.
src/types/api.ts Extended ApiLayout enum and Projection type; added new types TokensMarketDataRow and TokensMarketData for structured market data.
src/utils/common.ts Added utility function getShorterTimeUnits for shortening formatted time units in strings.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant TokensWithMarketDataTile
    participant TokenMarketDataRow
    participant LeftColumnTokenMarketDataRow
    participant RightColumnTokenMarketDataRow
    participant TokenLogoMarketDataRow

    User->>TokensWithMarketDataTile: Renders with data
    TokensWithMarketDataTile->>TokenMarketDataRow: For each row, render
    TokenMarketDataRow->>TokenLogoMarketDataRow: Render token and chain logos
    TokenMarketDataRow->>LeftColumnTokenMarketDataRow: Render left column data
    TokenMarketDataRow->>RightColumnTokenMarketDataRow: Render right column data
Loading

Possibly related PRs

Suggested reviewers

  • IAmKio

Poem

In rows of green and numbers bright,
Tokens shimmer in the data light.
Logos safe from broken dreams,
Decorators frame the market streams.
Copy links and times that fly,
Rabbits hop as tests pass by—
A tile of tokens, oh my! 🐇✨


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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

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

CodeRabbit Commands (Invoked using PR comments)

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

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

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

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Apr 23, 2025

Deploying x with  Cloudflare Pages  Cloudflare Pages

Latest commit: b0ffb03
Status: ✅  Deploy successful!
Preview URL: https://7d24dfb9.x-e62.pages.dev
Branch Preview URL: https://feat-pro-3225-new-token-tile.x-e62.pages.dev

View logs

@github-actions github-actions bot temporarily deployed to Preview (feat/PRO-3225/new-token-tiles) April 23, 2025 13:37 Inactive
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: 7

🧹 Nitpick comments (8)
src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx (1)

1-43: TileTitle component implementation looks good but filename appears redundant

The component correctly handles optional title and decorators with proper image error handling to prevent broken images from displaying.

The filename "TitleTitle.tsx" seems redundant. Consider renaming to "TileTitle.tsx" to match the component name.

src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx (2)

19-25: Consider adding error handling for navigation and extracting conditional styling logic.

The click handler doesn't include error handling for navigation. Additionally, the conditional border styling logic is complex and embedded directly in the className.

Consider extracting the border styling logic to a separate function:

- <div
-   className={`flex w-full h-full items-center justify-between gap-2 py-3 border-b-[1px] border-[#25232D]
-   ${listNumber === 8 && 'desktop:border-b-0 tablet:border-b-0 mobile:border-b-0'} 
-   ${listNumber === 4 && 'desktop:border-b-0'}
-   ${data.link && 'cursor-pointer'}`}
-   onClick={() => (data.link ? navigate(`${data.link}`) : undefined)}
- >
+ <div
+   className={`flex w-full h-full items-center justify-between gap-2 py-3 border-b-[1px] border-[#25232D]
+   ${getBorderClasses(listNumber)}
+   ${data.link && 'cursor-pointer'}`}
+   onClick={() => handleRowClick(data.link)}
+ >

Then add these functions:

const getBorderClasses = (listNumber) => {
  if (listNumber === 8) return 'desktop:border-b-0 tablet:border-b-0 mobile:border-b-0';
  if (listNumber === 4) return 'desktop:border-b-0';
  return '';
};

const handleRowClick = (link) => {
  if (!link) return;
  try {
    navigate(`${link}`);
  } catch (error) {
    console.error('Navigation error:', error);
  }
};

20-20: Consider using theme variables instead of hardcoded colors.

The border color #25232D is hardcoded, which might create inconsistency if the theme colors change.

If you have a theming system, consider using theme variables:

- className={`flex w-full h-full items-center justify-between gap-2 py-3 border-b-[1px] border-[#25232D]
+ className={`flex w-full h-full items-center justify-between gap-2 py-3 border-b-[1px] border-border-color

Where border-color would be defined in your Tailwind theme.

src/apps/pillarx-app/components/TokenMarketDataRow/RightColumnTokenMarketDataRow.tsx (2)

24-27: Simplify complex conditional class names.

The conditional class logic is complex and might be difficult to maintain.

Extract the logic to helper functions:

- <Body
-   className={`font-normal ${rightColumn?.line1?.direction === 'UP' && 'desktop:text-market_row_green tablet:text-market_row_green'} ${rightColumn?.line1?.direction === 'DOWN' && 'desktop:text-percentage_red tablet:text-percentage_red'} mobile:text-white desktop:text-base tablet:text-base mobile:text-sm`}
- >
+ <Body
+   className={`font-normal ${getDirectionTextColor(rightColumn?.line1?.direction)} mobile:text-white desktop:text-base tablet:text-base mobile:text-sm`}
+ >

Add this helper function:

const getDirectionTextColor = (direction) => {
  if (direction === 'UP') return 'desktop:text-market_row_green tablet:text-market_row_green';
  if (direction === 'DOWN') return 'desktop:text-percentage_red tablet:text-percentage_red';
  return '';
};

32-40: Simplify direction check condition.

The condition checks for both 'UP' and 'DOWN' when the icon color is determined by another condition anyway.

- {(rightColumn?.line1?.direction === 'UP' ||
-   rightColumn?.line1?.direction === 'DOWN') && (
+ {rightColumn?.line1?.direction && (
    <TbTriangleFilled
      size={6}
      color={
        rightColumn?.line1?.direction === 'UP' ? '#5CFF93' : '#FF366C'
      }
    />
  )}
src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx (1)

25-42: Consider extracting timestamp formatting to a utility function

The timestamp formatting logic is complex and could be reused elsewhere. Consider extracting it to a separate utility function.

+ // utils/formatters.ts
+ export const formatRelativeTime = (timestamp: number): string => {
+   let formattedTime = formatDistanceToNowStrict(
+     DateTime.fromSeconds(timestamp || 0).toISO() || '',
+     { addSuffix: true }
+   );
+
+   // Replace long units with shorter units and delete white space before the units
+   return formattedTime
+     .replace('seconds', 's')
+     .replace('second', 's')
+     .replace('minutes', 'min')
+     .replace('minute', 'min')
+     .replace('hours', 'h')
+     .replace('hour', 'h')
+     .replace('days', 'd')
+     .replace('day', 'd')
+     .replace('months', 'mo')
+     .replace('month', 'mo')
+     .replace(/(\d+)\s+(?=[a-zA-Z])/g, '$1');
+ };

Then in your component:

- let timestamp = formatDistanceToNowStrict(
-   DateTime.fromSeconds(leftColumn?.line2?.timestamp || 0).toISO() || '',
-   { addSuffix: true }
- );
-
- // Replace long units with shorter units and delete white space before the units
- timestamp = timestamp
-   .replace('seconds', 's')
-   .replace('second', 's')
-   .replace('minutes', 'min')
-   .replace('minute', 'min')
-   .replace('hours', 'h')
-   .replace('hour', 'h')
-   .replace('days', 'd')
-   .replace('day', 'd')
-   .replace('months', 'mo')
-   .replace('month', 'mo')
-   .replace(/(\d+)\s+(?=[a-zA-Z])/g, '$1');

+ const timestamp = formatRelativeTime(leftColumn?.line2?.timestamp || 0);
src/apps/pillarx-app/components/TokenMarketDataRow/TokenLogoMarketDataRow.tsx (2)

31-41: Add validation for tokenName when using it for fallback display

The component should validate that tokenName is not empty before using it for initials.

{(!tokenLogo || isBrokenImage) && (
  <span className="absolute inset-0 flex items-center justify-center text-white text-base font-normal">
-   {tokenName?.slice(0, 2)}
+   {tokenName?.trim() ? tokenName.slice(0, 2) : '??'}
  </span>
)}

44-53: Add a data-testid attribute to chain logo for testing

For consistency with the token logo, add a data-testid attribute to the chain logo image.

<img
  src={chainLogo}
  alt="logo"
  className="w-full h-full object-contain"
+ data-testid="chain-logo"
  onError={() => setIsBrokenImageChain(true)}
/>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d960f41 and 2e89e35.

⛔ Files ignored due to path filters (6)
  • src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/RightColumnTokenMarketDataRow.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/images/token-market-data-copy.png is excluded by !**/*.png
📒 Files selected for processing (12)
  • src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokenMarketDataRow/RightColumnTokenMarketDataRow.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokenMarketDataRow/TokenLogoMarketDataRow.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokenMarketDataRow/tests/LeftColumnTokenMarketDataRow.test.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokenMarketDataRow/tests/RightColumnTokenMarketDataRow.test.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx (1 hunks)
  • src/apps/pillarx-app/tailwind.pillarx.config.js (1 hunks)
  • src/apps/pillarx-app/utils/configComponent.ts (2 hunks)
  • src/types/api.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx (2)
src/types/api.ts (1)
  • TileTitle (354-356)
src/apps/simpleswap/components/NewCoinsDropdown/styles.ts (1)
  • Body (29-35)
src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx (1)
src/types/api.ts (3)
  • Projection (173-185)
  • TokensMarketData (164-171)
  • TileTitle (354-356)
🪛 Biome (1.9.4)
src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx

[error] 47-62: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (25)
src/apps/pillarx-app/tailwind.pillarx.config.js (1)

25-25: Positive market indicator color addition looks good!

The new color market_row_green: '#5CFF93' is appropriately added to the color palette and follows the existing naming conventions. This will be used for styling positive market direction indicators in the token market data components.

src/types/api.ts (4)

9-9: New ApiLayout enum value added correctly

Adding TOKENS_WITH_MARKET_DATA to the ApiLayout enum properly extends the available layout options for the application, allowing for the new token tiles feature.


134-162: Well-structured TokensMarketDataRow type definition

The type definition is comprehensive with all fields marked as optional, which provides flexibility when implementing this feature. The nested structure clearly separates token display concerns between left and right columns.


164-171: TokensMarketData type is properly organized

The type includes an optional title with configurable decorators and a collection of rows. This structure aligns well with the UI components that will render this data.


177-182: Projection type correctly updated to include TokensMarketData

The union type has been properly extended to include the new TokensMarketData type, ensuring that the API projection system can handle the new token market data tile format.

src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx (2)

16-17: Good use of useState for image error handling

Using state to track broken images is a good practice. It prevents the component from attempting to render broken images, which improves user experience.


20-38: Well-structured component rendering with proper conditional logic

The component's render logic is clean with appropriate conditional rendering based on prop availability and image loading state. The Tailwind classes are appropriate for the layout.

src/apps/pillarx-app/utils/configComponent.ts (2)

12-12: Import for the new TokensWithMarketDataTile component added correctly

The import statement follows the existing pattern and imports the new tile component.


26-26: New component correctly registered in the component map

The TokensWithMarketDataTile component is properly mapped to the ApiLayout.TOKENS_WITH_MARKET_DATA enum value, ensuring it can be rendered when this layout type is specified.

src/apps/pillarx-app/components/TokenMarketDataRow/tests/LeftColumnTokenMarketDataRow.test.tsx (1)

1-71: Good test coverage for the LeftColumnTokenMarketDataRow component.

The test suite is well-structured with a comprehensive mock data object and tests that cover:

  • Component rendering and snapshot matching
  • Presence of key text elements
  • Rendering of volume and liquidity information
  • Graceful handling of missing data

This follows good testing practices for React components with appropriate assertions.

src/apps/pillarx-app/components/TokenMarketDataRow/tests/RightColumnTokenMarketDataRow.test.tsx (1)

1-80: Well-structured test suite that covers both happy paths and edge cases.

The tests thoroughly verify the component's behavior with:

  • Standard rendering and snapshot matching
  • Verification of price, percentage, and transaction count display
  • Handling of missing percentage data
  • Graceful degradation when line1 data is entirely missing

This comprehensive approach ensures the component will behave predictably with varying data inputs.

src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx (1)

30-34: 🛠️ Refactor suggestion

Add null checks for data.leftColumn properties.

The component doesn't check if data.leftColumn exists before accessing its nested properties, which could cause runtime errors if the data structure is incomplete.

Add null checks to avoid potential errors:

<TokenLogoMarketDataRow
-  tokenLogo={data.leftColumn?.token?.primaryImage}
-  chainLogo={data.leftColumn?.token?.secondaryImage}
-  tokenName={data.leftColumn?.line1?.text2}
+  tokenLogo={data.leftColumn?.token?.primaryImage || undefined}
+  chainLogo={data.leftColumn?.token?.secondaryImage || undefined}
+  tokenName={data.leftColumn?.line1?.text2 || undefined}
/>

Likely an incorrect or invalid review comment.

src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx (7)

14-86: LGTM: Good test mock data setup

The mock data is comprehensive and well-structured, providing a clear representation of the expected data format for testing.


88-99: Good snapshot test implementation

The snapshot test is properly implemented within a MemoryRouter to handle the links correctly.


101-114: Well-defined title and decorators test

This test provides good coverage for the TileTitle component integration.


116-140: Thorough data rendering test

The test effectively verifies all token data fields are rendered correctly for both token rows.


142-151: Loading state handled properly

The test correctly verifies the component doesn't render during loading state.


153-169: Empty data case handled correctly

Good test case to verify the component doesn't render when rows are empty.


171-190: Row limit test is valuable

Excellent test case to verify the component respects the 8-row limit, which matches the implementation logic.

src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx (3)

9-12: LGTM: Clear prop type definition

The prop types are clearly defined for the component, making it easy to understand the expected inputs.


22-31: Clean data preparation and handling

The row limiting and column splitting logic is clear, and the null rendering for edge cases is appropriate.


39-43: Good component composition

The TileTitle component is properly used with all the necessary props.

src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx (1)

69-86: Good responsive design for secondary information

The layout for timestamp, volume and liquidity is well-structured with appropriate visibility rules for mobile.

src/apps/pillarx-app/components/TokenMarketDataRow/TokenLogoMarketDataRow.tsx (2)

17-19: Good use of state for handling broken images

Using separate state variables for token and chain logos properly handles broken image scenarios.


20-55: Well-structured token logo component with proper fallbacks

The component handles image loading, broken images, and fallbacks appropriately. The responsive design is also well-implemented.

@github-actions github-actions bot temporarily deployed to Preview (feat/PRO-3225/new-token-tiles) April 23, 2025 15:08 Inactive
Copy link
Collaborator

@IAmKio IAmKio left a comment

Choose a reason for hiding this comment

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

Just a few questions and concerns but otherwise great work!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the file name supposed to be TileTitle?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes :) I thought this could be in the future a re-usable component for any Tile Title

Comment on lines 31 to 42
timestamp = timestamp
.replace('seconds', 's')
.replace('second', 's')
.replace('minutes', 'min')
.replace('minute', 'min')
.replace('hours', 'h')
.replace('hour', 'h')
.replace('days', 'd')
.replace('day', 'd')
.replace('months', 'mo')
.replace('month', 'mo')
.replace(/(\d+)\s+(?=[a-zA-Z])/g, '$1');
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is quite useful as a utility - could be moved into a utils file?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure! Done!

>
<div className="flex items-center flex-1 min-w-0">
<Body className="desktop:text-base tablet:text-base mobile:text-sm font-normal text-white/[0.5] mr-4 mobile:mr-2.5">
0{listNumber}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just a note on the 0 here - this list, in future, could be more than 9 entries - could we remove the 0?

Copy link
Collaborator Author

@RanaBug RanaBug Apr 24, 2025

Choose a reason for hiding this comment

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

Ok I have now made changes to make this work

Comment on lines 22 to 27
// Limit the rows to the first 8 items
const limitedRows = dataTokens?.rows?.slice(0, 8) || [];

// Divide the rows into two separate columns
const leftColumn = limitedRows.slice(0, 4);
const rightColumn = limitedRows.slice(4, 8);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Okay i can see what's going on here (see my previous comment) - we definitely need to cater fo the fact that there may be a situation where we want to show more than 8 entries... we can check the requirement but i think it's a better idea to accommodate for bigger lists just incase

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok I have now made changes to make this work

@github-actions github-actions bot temporarily deployed to Preview (staging) April 24, 2025 12:09 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/utils/common.ts (1)

43-57: Improve the time unit abbreviation function.

The new getShorterTimeUnits function works correctly for basic cases, but there are some improvements that could be made:

  1. Consider a more descriptive name like abbreviateTimeUnits or shortenTimeFormat since the function transforms a string rather than "getting" units.

  2. The multiple .replace() calls could be replaced with a more efficient approach using a mapping object:

-export const getShorterTimeUnits = (formattedDistanceToNowDate: string) => {
-  // Replace long units with shorter units and delete white space before the units
-  return formattedDistanceToNowDate
-    .replace('seconds', 's')
-    .replace('second', 's')
-    .replace('minutes', 'min')
-    .replace('minute', 'min')
-    .replace('hours', 'h')
-    .replace('hour', 'h')
-    .replace('days', 'd')
-    .replace('day', 'd')
-    .replace('months', 'mo')
-    .replace('month', 'mo')
-    .replace(/(\d+)\s+(?=[a-zA-Z])/g, '$1');
-};
+export const getShorterTimeUnits = (formattedDistanceToNowDate: string) => {
+  // Map of time units to their shorter forms
+  const unitMap: Record<string, string> = {
+    seconds: 's',
+    second: 's',
+    minutes: 'min',
+    minute: 'min',
+    hours: 'h',
+    hour: 'h',
+    days: 'd',
+    day: 'd',
+    months: 'mo',
+    month: 'mo',
+  };
+  
+  // Replace long units with shorter units
+  let shortened = formattedDistanceToNowDate;
+  Object.entries(unitMap).forEach(([longUnit, shortUnit]) => {
+    shortened = shortened.replace(new RegExp(longUnit, 'g'), shortUnit);
+  });
+  
+  // Remove spaces between numbers and units
+  return shortened.replace(/(\d+)\s+(?=[a-zA-Z])/g, '$1');
+};
  1. Consider adding some basic validation for the input string.

  2. Add unit tests to verify the function works with various inputs, including edge cases.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c786b68 and e720cb0.

⛔ Files ignored due to path filters (4)
  • src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx (1 hunks)
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx (1 hunks)
  • src/utils/common.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx
  • src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx
  • src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: lint
  • GitHub Check: unit-tests
  • GitHub Check: build
  • GitHub Check: Cloudflare Pages

@github-actions github-actions bot requested a deployment to Preview (feat/PRO-3225/new-token-tiles) April 24, 2025 12:56 Abandoned
@github-actions github-actions bot temporarily deployed to Preview (feat/PRO-3225/new-token-tiles) April 24, 2025 13:04 Inactive
Copy link
Collaborator

@IAmKio IAmKio left a comment

Choose a reason for hiding this comment

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

LGTM!

@github-actions github-actions bot temporarily deployed to Preview (feat/PRO-3225/new-token-tiles) April 24, 2025 14:00 Inactive
@RanaBug RanaBug merged commit 1688714 into staging Apr 24, 2025
7 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jul 10, 2025
3 tasks
This was referenced Jul 26, 2025
@coderabbitai coderabbitai bot mentioned this pull request Oct 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants