From 2e89e35208072c93c7e770a227210a964a400c64 Mon Sep 17 00:00:00 2001 From: RanaBug Date: Wed, 23 Apr 2025 14:34:29 +0100 Subject: [PATCH 1/5] design implementation of new token tiles --- .../DisplayCollectionImage.test.tsx.snap | 67 +- .../__snapshots__/PointsTile.test.tsx.snap | 4 +- .../components/TileTitle/TitleTitle.tsx | 42 ++ .../LeftColumnTokenMarketDataRow.tsx | 91 +++ .../RightColumnTokenMarketDataRow.tsx | 58 ++ .../TokenLogoMarketDataRow.tsx | 58 ++ .../TokenMarketDataRow/TokenMarketDataRow.tsx | 44 ++ .../LeftColumnTokenMarketDataRow.test.tsx | 71 ++ .../RightColumnTokenMarketDataRow.test.tsx | 80 ++ ...LeftColumnTokenMarketDataRow.test.tsx.snap | 172 +++++ ...ightColumnTokenMarketDataRow.test.tsx.snap | 178 +++++ .../TokensWithMarketDataTile.tsx | 69 ++ .../test/TokensWithMarketDataTile.test.tsx | 191 +++++ .../TokensWithMarketDataTile.test.tsx.snap | 706 ++++++++++++++++++ .../images/token-market-data-copy.png | Bin 0 -> 489 bytes .../pillarx-app/tailwind.pillarx.config.js | 1 + src/apps/pillarx-app/utils/configComponent.ts | 2 + src/types/api.ts | 47 +- 18 files changed, 1838 insertions(+), 43 deletions(-) create mode 100644 src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx create mode 100644 src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx create mode 100644 src/apps/pillarx-app/components/TokenMarketDataRow/RightColumnTokenMarketDataRow.tsx create mode 100644 src/apps/pillarx-app/components/TokenMarketDataRow/TokenLogoMarketDataRow.tsx create mode 100644 src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx create mode 100644 src/apps/pillarx-app/components/TokenMarketDataRow/tests/LeftColumnTokenMarketDataRow.test.tsx create mode 100644 src/apps/pillarx-app/components/TokenMarketDataRow/tests/RightColumnTokenMarketDataRow.test.tsx create mode 100644 src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap create mode 100644 src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/RightColumnTokenMarketDataRow.test.tsx.snap create mode 100644 src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx create mode 100644 src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx create mode 100644 src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap create mode 100644 src/apps/pillarx-app/images/token-market-data-copy.png diff --git a/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap b/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap index 596b96d8..b9d2dc0d 100644 --- a/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap +++ b/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap @@ -43,49 +43,36 @@ exports[` renders correctly and matches snapshot witho - - - - - - - - - + - - - - + y2={40} + /> + `; diff --git a/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap b/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap index 2dd9105e..8e168440 100644 --- a/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap +++ b/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap @@ -160,7 +160,7 @@ exports[` renders correctly and matches snapshot 1`] = ` class="desktop:text-[22px] tablet:text-lg mobile:text-lg text-white" data-testid="points-formatted-timestamp" > - -15 + -54 @@ -413,7 +413,7 @@ exports[` renders correctly and matches snapshot 1`] = ` class="desktop:text-[22px] tablet:text-lg mobile:text-lg text-white" data-testid="points-formatted-timestamp" > - -15 + -54 diff --git a/src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx b/src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx new file mode 100644 index 00000000..1fbea51f --- /dev/null +++ b/src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx @@ -0,0 +1,42 @@ +import { useState } from 'react'; + +// components +import Body from '../Typography/Body'; + +type TileTitleProps = { + title?: string; + leftDecorator?: string; + rightDecorator?: string; +}; +const TileTitle = ({ + title, + leftDecorator, + rightDecorator, +}: TileTitleProps) => { + const [isBrokenImageRight, setIsBrokenImageRight] = useState(false); + const [isBrokenImageLeft, setIsBrokenImageLeft] = useState(false); + + return ( +
+ {leftDecorator && !isBrokenImageLeft && ( + left-decorator-image setIsBrokenImageLeft(true)} + /> + )} + {title && {title}} + {rightDecorator && !isBrokenImageRight && ( + right-decorator-image setIsBrokenImageRight(true)} + /> + )} +
+ ); +}; + +export default TileTitle; diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx b/src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx new file mode 100644 index 00000000..3fcefbe5 --- /dev/null +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx @@ -0,0 +1,91 @@ +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +import { formatDistanceToNowStrict } from 'date-fns'; +import { DateTime } from 'luxon'; +import CopyToClipboard from 'react-copy-to-clipboard'; + +// types +import { TokensMarketDataRow } from '../../../../types/api'; + +// components +import Body from '../Typography/Body'; +import BodySmall from '../Typography/BodySmall'; + +// images +import CopyIcon from '../../images/token-market-data-copy.png'; + +type LeftColumnTokenMarketDataRowProps = { + data: TokensMarketDataRow; +}; + +const LeftColumnTokenMarketDataRow = ({ + data, +}: LeftColumnTokenMarketDataRowProps) => { + const { leftColumn } = data; + + 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'); + + return ( +
+
+ {leftColumn?.line1?.text1 && ( + + {leftColumn?.line1?.text1} + + )} + {leftColumn?.line1?.text2 && ( + + {leftColumn?.line1?.text2} + + )} + {leftColumn?.line1?.copyLink && ( + + copy-token-address e.stopPropagation()} + /> + + )} +
+
+ {timestamp && ( + + {timestamp} + + )} + {leftColumn?.line2?.volume && ( + + Vol:{' '} + {leftColumn?.line2?.volume} + + )} + {leftColumn?.line2?.liquidity && ( + + Liq:{' '} + {leftColumn?.line2?.liquidity} + + )} +
+
+ ); +}; + +export default LeftColumnTokenMarketDataRow; diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/RightColumnTokenMarketDataRow.tsx b/src/apps/pillarx-app/components/TokenMarketDataRow/RightColumnTokenMarketDataRow.tsx new file mode 100644 index 00000000..f4c49afa --- /dev/null +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/RightColumnTokenMarketDataRow.tsx @@ -0,0 +1,58 @@ +import { TbTriangleFilled } from 'react-icons/tb'; + +// types +import { TokensMarketDataRow } from '../../../../types/api'; + +// components +import Body from '../Typography/Body'; +import BodySmall from '../Typography/BodySmall'; + +type RightColumnTokenMarketDataRowProps = { + data: TokensMarketDataRow; +}; + +const RightColumnTokenMarketDataRow = ({ + data, +}: RightColumnTokenMarketDataRowProps) => { + const { rightColumn } = data; + + return ( +
+
+ {rightColumn?.line1?.price && ( + + {rightColumn?.line1?.price} + + )} +
+ {(rightColumn?.line1?.direction === 'UP' || + rightColumn?.line1?.direction === 'DOWN') && ( + + )} + {rightColumn?.line1?.percentage && ( + + {rightColumn?.line1?.percentage} + + )} +
+
+ {rightColumn?.line2?.transactionCount && ( + + Txs:{' '} + {rightColumn?.line2?.transactionCount} + + )} +
+ ); +}; + +export default RightColumnTokenMarketDataRow; diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/TokenLogoMarketDataRow.tsx b/src/apps/pillarx-app/components/TokenMarketDataRow/TokenLogoMarketDataRow.tsx new file mode 100644 index 00000000..ced6bb50 --- /dev/null +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/TokenLogoMarketDataRow.tsx @@ -0,0 +1,58 @@ +import { useState } from 'react'; + +// components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; + +type TokenLogoMarketDataRowProps = { + tokenLogo?: string; + chainLogo?: string; + tokenName?: string; +}; + +const TokenLogoMarketDataRow = ({ + tokenLogo, + chainLogo, + tokenName, +}: TokenLogoMarketDataRowProps) => { + const [isBrokenImage, setIsBrokenImage] = useState(false); + const [isBrokenImageChain, setIsBrokenImageChain] = useState(false); + + return ( +
+ {tokenLogo && !isBrokenImage ? ( + token-logo setIsBrokenImage(true)} + /> + ) : ( +
+ +
+ )} + + {/* Overlay text when no logo available */} + {(!tokenLogo || isBrokenImage) && ( + + {tokenName?.slice(0, 2)} + + )} + + {/* Blockchain logo overlapping when only one blockchain for this token */} + {chainLogo && !isBrokenImageChain ? ( +
+ logo setIsBrokenImageChain(true)} + /> +
+ ) : null} +
+ ); +}; + +export default TokenLogoMarketDataRow; diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx b/src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx new file mode 100644 index 00000000..2d9532e7 --- /dev/null +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx @@ -0,0 +1,44 @@ +import { useNavigate } from 'react-router-dom'; + +// types +import { TokensMarketDataRow } from '../../../../types/api'; + +// components +import Body from '../Typography/Body'; +import LeftColumnTokenMarketDataRow from './LeftColumnTokenMarketDataRow'; +import RightColumnTokenMarketDataRow from './RightColumnTokenMarketDataRow'; +import TokenLogoMarketDataRow from './TokenLogoMarketDataRow'; + +type TokenMarketDataRowProps = { + data: TokensMarketDataRow; + listNumber: number; +}; +const TokenMarketDataRow = ({ data, listNumber }: TokenMarketDataRowProps) => { + const navigate = useNavigate(); + return ( +
(data.link ? navigate(`${data.link}`) : undefined)} + > +
+ + 0{listNumber} + + + +
+
+ +
+
+ ); +}; + +export default TokenMarketDataRow; diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/tests/LeftColumnTokenMarketDataRow.test.tsx b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/LeftColumnTokenMarketDataRow.test.tsx new file mode 100644 index 00000000..aa842d61 --- /dev/null +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/LeftColumnTokenMarketDataRow.test.tsx @@ -0,0 +1,71 @@ +import { render, screen } from '@testing-library/react'; + +// components +import LeftColumnTokenMarketDataRow from '../LeftColumnTokenMarketDataRow'; + +const ethTokenRow = { + link: 'token-atlas?someLink=true', + leftColumn: { + token: { + primaryImage: 'eth.png', + }, + line1: { + text1: 'ETH', + text2: 'Ethereum', + copyLink: '0xD76b5c2A23ef78368d8E34288B5b65D616B746aE', + }, + line2: { + timestamp: 1745331519, + volume: '1.2m', + liquidity: '$30,123', + }, + }, + rightColumn: { + line1: { + price: '$0.042188', + direction: 'UP', + percentage: '20.1%', + }, + line2: { + transactionCount: '1823', + }, + }, +}; + +describe(' - ETH token row', () => { + it('renders and matches snapshot', () => { + const tree = render(); + expect(tree).toMatchSnapshot(); + }); + + it('renders text1 and text2', () => { + render(); + expect(screen.getByText('ETH')).toBeInTheDocument(); + expect(screen.getByText('Ethereum')).toBeInTheDocument(); + }); + + it('renders volume and liquidity', () => { + render(); + expect(screen.getByText(/Vol:/)).toBeInTheDocument(); + expect(screen.getByText('1.2m')).toBeInTheDocument(); + expect(screen.getByText(/Liq:/)).toBeInTheDocument(); + expect(screen.getByText('$30,123')).toBeInTheDocument(); + }); + + it('does not break if some values are missing', () => { + const incomplete = { + leftColumn: { + line1: { + text1: 'ETH', + }, + line2: {}, + }, + }; + + render(); + + expect(screen.getByText('ETH')).toBeInTheDocument(); + expect(screen.queryByText(/Vol:/)).not.toBeInTheDocument(); + expect(screen.queryByText(/Liq:/)).not.toBeInTheDocument(); + }); +}); diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/tests/RightColumnTokenMarketDataRow.test.tsx b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/RightColumnTokenMarketDataRow.test.tsx new file mode 100644 index 00000000..7d0f6ea0 --- /dev/null +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/RightColumnTokenMarketDataRow.test.tsx @@ -0,0 +1,80 @@ +import { render, screen } from '@testing-library/react'; + +// components +import RightColumnTokenMarketDataRow from '../RightColumnTokenMarketDataRow'; + +const ethTokenRow = { + link: 'token-atlas?someLink=true', + leftColumn: { + token: { + primaryImage: 'eth.png', + }, + line1: { + text1: 'ETH', + text2: 'Ethereum', + copyLink: '0xD76b5c2A23ef78368d8E34288B5b65D616B746aE', + }, + line2: { + timestamp: 1745331519, + volume: '1.2m', + liquidity: '$30,123', + }, + }, + rightColumn: { + line1: { + price: '$0.042188', + direction: 'UP', + percentage: '20.1%', + }, + line2: { + transactionCount: '1823', + }, + }, +}; + +describe(' - ETH token row', () => { + it('renders and matches snapshot', () => { + const tree = render(); + expect(tree).toMatchSnapshot(); + }); + + it('renders percentage, price and transaction count ', () => { + render(); + + expect(screen.getByText('$0.042188')).toBeInTheDocument(); + expect(screen.getByText('20.1%')).toBeInTheDocument(); + expect(screen.getByText(/Txs:/)).toBeInTheDocument(); + expect(screen.getByText('1823')).toBeInTheDocument(); + }); + + it('renders with missing percentage', () => { + const noPercentageRow = { + ...ethTokenRow, + rightColumn: { + line1: { + price: '$0.999', + direction: 'UP', + }, + }, + }; + + render(); + expect(screen.getByText('$0.999')).toBeInTheDocument(); + expect(screen.queryByText('%')).not.toBeInTheDocument(); + }); + + it('renders only transaction count when line1 is missing', () => { + const noLine1Row = { + ...ethTokenRow, + rightColumn: { + line2: { + transactionCount: '9999', + }, + }, + }; + + render(); + expect(screen.getByText('9999')).toBeInTheDocument(); + expect(screen.queryByText('$')).not.toBeInTheDocument(); + }); +}); diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap new file mode 100644 index 00000000..e5da361c --- /dev/null +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap @@ -0,0 +1,172 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` - ETH token row renders and matches snapshot 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+

+ ETH +

+

+ Ethereum +

+ copy-token-address +
+
+

+ 23h ago +

+

+ + Vol: + + + 1.2m +

+

+ + Liq: + + + $30,123 +

+
+
+
+ , + "container":
+
+
+

+ ETH +

+

+ Ethereum +

+ copy-token-address +
+
+

+ 23h ago +

+

+ + Vol: + + + 1.2m +

+

+ + Liq: + + + $30,123 +

+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/RightColumnTokenMarketDataRow.test.tsx.snap b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/RightColumnTokenMarketDataRow.test.tsx.snap new file mode 100644 index 00000000..20e21812 --- /dev/null +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/RightColumnTokenMarketDataRow.test.tsx.snap @@ -0,0 +1,178 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` - ETH token row renders and matches snapshot 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+

+ $0.042188 +

+
+ + + + +

+ 20.1% +

+
+
+

+ + Txs: + + + 1823 +

+
+
+ , + "container":
+
+
+

+ $0.042188 +

+
+ + + + +

+ 20.1% +

+
+
+

+ + Txs: + + + 1823 +

+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx b/src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx new file mode 100644 index 00000000..d5211527 --- /dev/null +++ b/src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx @@ -0,0 +1,69 @@ +// types +import { Projection, TokensMarketData } from '../../../../types/api'; + +// components +import TileContainer from '../TileContainer/TileContainer'; +import TileTitle from '../TileTitle/TitleTitle'; +import TokenMarketDataRow from '../TokenMarketDataRow/TokenMarketDataRow'; + +type TokensWithMarketDataTileProps = { + data: Projection | undefined; + isDataLoading: boolean; +}; + +const TokensWithMarketDataTile = ({ + data, + isDataLoading, +}: TokensWithMarketDataTileProps) => { + const { data: tokensWithMarketData } = data || {}; + + const dataTokens = tokensWithMarketData as TokensMarketData | undefined; + + // 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); + + if (!data || !dataTokens?.rows?.length || isDataLoading) { + return null; + } + + return ( + // TO DO - replace the background with container background color once this has changed on Design + + + +
+ {Array.from({ length: 4 }).map((_, i) => ( + <> + {leftColumn[i] && ( + + )} + {rightColumn[i] && ( + + )} + + ))} +
+
+ ); +}; + +export default TokensWithMarketDataTile; diff --git a/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx new file mode 100644 index 00000000..00b25a74 --- /dev/null +++ b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx @@ -0,0 +1,191 @@ +import { render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; + +// components +import TokensWithMarketDataTile from '../TokensWithMarketDataTile'; + +// types +import { + ApiLayout, + Projection, + TokensMarketData, +} from '../../../../../types/api'; + +const mockTokensMarketData: Projection = { + id: 'tokens-with-market-data', + layout: ApiLayout.TOKENS_WITH_MARKET_DATA, + meta: {}, + data: { + title: { + text: 'Top Tokens', + leftDecorator: '🔥', + rightDecorator: '📈', + }, + rows: [ + { + link: 'token-atlas?someLink=true', + leftColumn: { + token: { + primaryImage: 'eth.png', + }, + line1: { + text1: 'ETH', + text2: 'Ethereum', + copyLink: '0xD76b5c2A23ef78368d8E34288B5b65D616B746aE', + }, + line2: { + timestamp: 1745331519, + volume: '1.2m', + liquidity: '$30,123', + }, + }, + rightColumn: { + line1: { + price: '$0.042188', + direction: 'UP', + percentage: '20.1%', + }, + line2: { + transactionCount: '1823', + }, + }, + }, + { + link: 'token-atlas?someLink=true', + leftColumn: { + token: { + primaryImage: + 'https://cryptologos.cc/logos/ethereum-eth-logo.svg?v=040', + secondaryImage: + 'https://cryptologos.cc/logos/optimism-ethereum-op-logo.svg?v=040', + }, + line1: { + text1: 'XDAI', + text2: 'XDAI', + copyLink: '0xD76b5c2A23ef78368d8E34288B5b65D616B746aE', + }, + line2: { + timestamp: 1745334519, + volume: '1.4m', + liquidity: '$3,123', + }, + }, + rightColumn: { + line1: { + price: '$1.062188', + direction: 'DOWN', + percentage: '3.1%', + }, + line2: { + transactionCount: '1423', + }, + }, + }, + ], + }, +}; + +describe('', () => { + it('renders and matches snapshot', () => { + const tree = render( + + + + ); + expect(tree).toMatchSnapshot(); + }); + + it('renders title and decorators', () => { + render( + + + + ); + + expect(screen.getByText('Top Tokens')).toBeInTheDocument(); + expect(screen.getByAltText('left-decorator-image')).toBeInTheDocument(); + expect(screen.getByAltText('right-decorator-image')).toBeInTheDocument(); + }); + + it('renders token rows with expected data', () => { + render( + + + + ); + + expect(screen.getByText('Ethereum')).toBeInTheDocument(); + expect(screen.getByText('ETH')).toBeInTheDocument(); + expect(screen.getByText('1.2m')).toBeInTheDocument(); + expect(screen.getByText('$30,123')).toBeInTheDocument(); + expect(screen.getByText('$0.042188')).toBeInTheDocument(); + expect(screen.getByText('20.1%')).toBeInTheDocument(); + expect(screen.getByText('1823')).toBeInTheDocument(); + + expect(screen.getAllByText('XDAI')).toHaveLength(2); + expect(screen.getByText('1.4m')).toBeInTheDocument(); + expect(screen.getByText('$3,123')).toBeInTheDocument(); + expect(screen.getByText('$1.062188')).toBeInTheDocument(); + expect(screen.getByText('3.1%')).toBeInTheDocument(); + expect(screen.getByText('1423')).toBeInTheDocument(); + }); + + it('does not render anything while loading', () => { + render( + + + + ); + + expect(screen.queryByText('Top Tokens')).not.toBeInTheDocument(); + expect(screen.queryByText('Ethereum')).not.toBeInTheDocument(); + }); + + it('does not render if data is missing or rows are empty', () => { + const emptyData: Projection = { + ...mockTokensMarketData, + data: { + ...mockTokensMarketData.data, + rows: [], + }, + }; + + render( + + + + ); + + expect(screen.queryByText('Top Tokens')).not.toBeInTheDocument(); + }); + + it('renders only up to 8 rows even if more are provided', () => { + const overfilledData: Projection = { + ...mockTokensMarketData, + data: { + ...mockTokensMarketData.data, + rows: new Array(10).fill( + (mockTokensMarketData.data as TokensMarketData).rows?.[0] + ), + }, + }; + + render( + + + + ); + + const ethItems = screen.getAllByText('Ethereum'); + expect(ethItems.length).toBeLessThanOrEqual(8); + }); +}); diff --git a/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap new file mode 100644 index 00000000..22fd61e5 --- /dev/null +++ b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap @@ -0,0 +1,706 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders and matches snapshot 1`] = ` +{ + "asFragment": [Function], + "baseElement": +
+
+
+ left-decorator-image +

+ Top Tokens +

+ right-decorator-image +
+
+
+
+

+ 0 + 1 +

+
+ token-logo +
+
+
+

+ ETH +

+

+ Ethereum +

+ copy-token-address +
+
+

+ 23h ago +

+

+ + Vol: + + + 1.2m +

+

+ + Liq: + + + $30,123 +

+
+
+
+
+
+
+

+ $0.042188 +

+
+ + + + +

+ 20.1% +

+
+
+

+ + Txs: + + + 1823 +

+
+
+
+
+
+

+ 0 + 2 +

+
+ token-logo +
+ logo +
+
+
+
+

+ XDAI +

+

+ XDAI +

+ copy-token-address +
+
+

+ 22h ago +

+

+ + Vol: + + + 1.4m +

+

+ + Liq: + + + $3,123 +

+
+
+
+
+
+
+

+ $1.062188 +

+
+ + + + +

+ 3.1% +

+
+
+

+ + Txs: + + + 1423 +

+
+
+
+
+
+
+ , + "container":
+
+
+ left-decorator-image +

+ Top Tokens +

+ right-decorator-image +
+
+
+
+

+ 0 + 1 +

+
+ token-logo +
+
+
+

+ ETH +

+

+ Ethereum +

+ copy-token-address +
+
+

+ 23h ago +

+

+ + Vol: + + + 1.2m +

+

+ + Liq: + + + $30,123 +

+
+
+
+
+
+
+

+ $0.042188 +

+
+ + + + +

+ 20.1% +

+
+
+

+ + Txs: + + + 1823 +

+
+
+
+
+
+

+ 0 + 2 +

+
+ token-logo +
+ logo +
+
+
+
+

+ XDAI +

+

+ XDAI +

+ copy-token-address +
+
+

+ 22h ago +

+

+ + Vol: + + + 1.4m +

+

+ + Liq: + + + $3,123 +

+
+
+
+
+
+
+

+ $1.062188 +

+
+ + + + +

+ 3.1% +

+
+
+

+ + Txs: + + + 1423 +

+
+
+
+
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/apps/pillarx-app/images/token-market-data-copy.png b/src/apps/pillarx-app/images/token-market-data-copy.png new file mode 100644 index 0000000000000000000000000000000000000000..3d7acfa30ecbc0367ef2ef539bdd892c51479f31 GIT binary patch literal 489 zcmV@~0drDELIAGL9O(c600d`2O+f$vv5yP8r!H8iP-l^G8)DkJ2DUQy$)7ar)0LiVW*;1@vLr-xa(Y}HWmU57>w!A8DP(p*O zsaeAw-ZH-yGq^!MY74;+EmihXnp-P*SEHuFK((2Ip}t2_5eJN#EdEjLH?AyvQ## zNKZ891d2V0hH0nl$4^8sE^z}pImlRztjd&cL{g Date: Wed, 23 Apr 2025 16:08:14 +0100 Subject: [PATCH 2/5] minor fix --- .../DisplayCollectionImage.test.tsx.snap | 63 +- .../__snapshots__/PointsTile.test.tsx.snap | 4 +- ...LeftColumnTokenMarketDataRow.test.tsx.snap | 4 +- .../TokensWithMarketDataTile.tsx | 4 +- .../TokensWithMarketDataTile.test.tsx.snap | 674 +++++++++--------- 5 files changed, 393 insertions(+), 356 deletions(-) diff --git a/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap b/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap index b9d2dc0d..4efc69a1 100644 --- a/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap +++ b/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap @@ -23,54 +23,63 @@ exports[` renders correctly and matches snapshot witho data-testid="random-avatar" fill="none" role="img" - viewBox="0 0 80 80" + viewBox="0 0 90 90" xmlns="http://www.w3.org/2000/svg" > - - - + + - + + + diff --git a/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap b/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap index 8e168440..69ef9a05 100644 --- a/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap +++ b/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap @@ -160,7 +160,7 @@ exports[` renders correctly and matches snapshot 1`] = ` class="desktop:text-[22px] tablet:text-lg mobile:text-lg text-white" data-testid="points-formatted-timestamp" > - -54 + -28 @@ -413,7 +413,7 @@ exports[` renders correctly and matches snapshot 1`] = ` class="desktop:text-[22px] tablet:text-lg mobile:text-lg text-white" data-testid="points-formatted-timestamp" > - -54 + -28 diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap index e5da361c..584cda6a 100644 --- a/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap @@ -33,7 +33,7 @@ exports[` - ETH token row renders and matches sn

- 23h ago + 1d ago

- ETH token row renders and matches sn

- 23h ago + 1d ago

{Array.from({ length: 4 }).map((_, i) => ( - <> +

{leftColumn[i] && ( )} - +
))} diff --git a/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap index 22fd61e5..1872f216 100644 --- a/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap +++ b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap @@ -30,6 +30,347 @@ exports[` renders and matches snapshot 1`] = `
+
+
+
+

+ 0 + 1 +

+
+ token-logo +
+
+
+

+ ETH +

+

+ Ethereum +

+ copy-token-address +
+
+

+ 1d ago +

+

+ + Vol: + + + 1.2m +

+

+ + Liq: + + + $30,123 +

+
+
+
+
+
+
+

+ $0.042188 +

+
+ + + + +

+ 20.1% +

+
+
+

+ + Txs: + + + 1823 +

+
+
+
+
+
+
+
+

+ 0 + 2 +

+
+ token-logo +
+ logo +
+
+
+
+

+ XDAI +

+

+ XDAI +

+ copy-token-address +
+
+

+ 24h ago +

+

+ + Vol: + + + 1.4m +

+

+ + Liq: + + + $3,123 +

+
+
+
+
+
+
+

+ $1.062188 +

+
+ + + + +

+ 3.1% +

+
+
+

+ + Txs: + + + 1423 +

+
+
+
+
+
+
+
+
+
+ , + "container":
+
+
+ left-decorator-image +

+ Top Tokens +

+ right-decorator-image +
+
+
- 23h ago + 1d ago

renders and matches snapshot 1`] = `

+
+
- 22h ago + 24h ago

renders and matches snapshot 1`] = `

- - - , - "container":
-
-
- left-decorator-image -

- Top Tokens -

- right-decorator-image -
-
-
-

- 0 - 1 -

-
- token-logo -
-
-
-

- ETH -

-

- Ethereum -

- copy-token-address -
-
-

- 23h ago -

-

- - Vol: - - - 1.2m -

-

- - Liq: - - - $30,123 -

-
-
-
-
-
-
-

- $0.042188 -

-
- - - - -

- 20.1% -

-
-
-

- - Txs: - - - 1823 -

-
-
-
+ class="contents" + />
-
-

- 0 - 2 -

-
- token-logo -
- logo -
-
-
-
-

- XDAI -

-

- XDAI -

- copy-token-address -
-
-

- 22h ago -

-

- - Vol: - - - 1.4m -

-

- - Liq: - - - $3,123 -

-
-
-
-
-
-
-

- $1.062188 -

-
- - - - -

- 3.1% -

-
-
-

- - Txs: - - - 1423 -

-
-
-
+ class="contents" + />
, From e720cb05fadeed485b57245beb7c0934d485ba15 Mon Sep 17 00:00:00 2001 From: RanaBug Date: Thu, 24 Apr 2025 13:09:21 +0100 Subject: [PATCH 3/5] fixes after review --- .../DisplayCollectionImage.test.tsx.snap | 75 +- .../__snapshots__/PointsTile.test.tsx.snap | 4 +- .../LeftColumnTokenMarketDataRow.tsx | 33 +- .../TokenMarketDataRow/TokenMarketDataRow.tsx | 15 +- ...LeftColumnTokenMarketDataRow.test.tsx.snap | 4 +- .../TokensWithMarketDataTile.tsx | 73 +- .../test/TokensWithMarketDataTile.test.tsx | 58 +- .../TokensWithMarketDataTile.test.tsx.snap | 650 +++++++++++++++++- src/utils/common.ts | 16 + 9 files changed, 783 insertions(+), 145 deletions(-) diff --git a/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap b/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap index 4efc69a1..c6cf8ad1 100644 --- a/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap +++ b/src/apps/pillarx-app/components/MediaGridCollection/tests/__snapshots__/DisplayCollectionImage.test.tsx.snap @@ -23,65 +23,70 @@ exports[` renders correctly and matches snapshot witho data-testid="random-avatar" fill="none" role="img" - viewBox="0 0 90 90" + viewBox="0 0 80 80" xmlns="http://www.w3.org/2000/svg" > - - - - - - - + + + + + + + `; diff --git a/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap b/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap index 69ef9a05..36e51197 100644 --- a/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap +++ b/src/apps/pillarx-app/components/PointsTile/test/__snapshots__/PointsTile.test.tsx.snap @@ -160,7 +160,7 @@ exports[` renders correctly and matches snapshot 1`] = ` class="desktop:text-[22px] tablet:text-lg mobile:text-lg text-white" data-testid="points-formatted-timestamp" > - -28 + -29 @@ -413,7 +413,7 @@ exports[` renders correctly and matches snapshot 1`] = ` class="desktop:text-[22px] tablet:text-lg mobile:text-lg text-white" data-testid="points-formatted-timestamp" > - -28 + -29 diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx b/src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx index 3fcefbe5..f22ad5cc 100644 --- a/src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/LeftColumnTokenMarketDataRow.tsx @@ -1,11 +1,14 @@ /* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ -import { formatDistanceToNowStrict } from 'date-fns'; +import { formatDistanceToNowStrict, isValid, parseISO } from 'date-fns'; import { DateTime } from 'luxon'; import CopyToClipboard from 'react-copy-to-clipboard'; // types import { TokensMarketDataRow } from '../../../../types/api'; +// utils +import { getShorterTimeUnits } from '../../../../utils/common'; + // components import Body from '../Typography/Body'; import BodySmall from '../Typography/BodySmall'; @@ -22,24 +25,20 @@ const LeftColumnTokenMarketDataRow = ({ }: LeftColumnTokenMarketDataRowProps) => { const { leftColumn } = data; - let timestamp = formatDistanceToNowStrict( - DateTime.fromSeconds(leftColumn?.line2?.timestamp || 0).toISO() || '', - { addSuffix: true } - ); + const timestampToISO = + DateTime.fromSeconds(leftColumn?.line2?.timestamp || 0).toISO() || ''; + + const ISOToDate = parseISO(timestampToISO); + + let timestamp = isValid(ISOToDate) + ? formatDistanceToNowStrict( + DateTime.fromSeconds(leftColumn?.line2?.timestamp || 0).toISO() || '', + { addSuffix: true } + ) + : undefined; // 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'); + timestamp = timestamp && getShorterTimeUnits(timestamp); return (
diff --git a/src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx b/src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx index 2d9532e7..e6705380 100644 --- a/src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx +++ b/src/apps/pillarx-app/components/TokenMarketDataRow/TokenMarketDataRow.tsx @@ -12,20 +12,27 @@ import TokenLogoMarketDataRow from './TokenLogoMarketDataRow'; type TokenMarketDataRowProps = { data: TokensMarketDataRow; listNumber: number; + isLastNumber: boolean; + isMiddleNumber: boolean; }; -const TokenMarketDataRow = ({ data, listNumber }: TokenMarketDataRowProps) => { +const TokenMarketDataRow = ({ + data, + listNumber, + isLastNumber, + isMiddleNumber, +}: TokenMarketDataRowProps) => { const navigate = useNavigate(); return (
(data.link ? navigate(`${data.link}`) : undefined)} >
- 0{listNumber} + {listNumber > 0 && listNumber < 10 ? `0${listNumber}` : listNumber} - ETH token row renders and matches sn

- 1d ago + 2d ago

- ETH token row renders and matches sn

- 1d ago + 2d ago

+

+ {/* Mobile: 1 column */} +
+ {dataTokens.rows.map((row, index) => ( + + ))} +
-
- {Array.from({ length: 4 }).map((_, i) => ( -
- {leftColumn[i] && ( - - )} - {rightColumn[i] && ( - - )} -
- ))} + {/* Desktop: 2 columns */} +
+ {Array.from({ length: midLength }).map((_, i) => ( +
+ {dataTokens?.rows?.slice(0, midLength)[i] && ( + + )} + {dataTokens?.rows?.slice(midLength, dataTokens.rows.length)[ + i + ] && ( + + )} +
+ ))} +
); diff --git a/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx index 00b25a74..63ce5c18 100644 --- a/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx +++ b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/TokensWithMarketDataTile.test.tsx @@ -1,4 +1,4 @@ -import { render, screen } from '@testing-library/react'; +import { render, screen, within } from '@testing-library/react'; import { MemoryRouter } from 'react-router-dom'; // components @@ -113,8 +113,8 @@ describe('', () => { expect(screen.getByAltText('right-decorator-image')).toBeInTheDocument(); }); - it('renders token rows with expected data', () => { - render( + it('renders token rows with expected data (mobile layout)', () => { + const { container } = render( ', () => { ); - expect(screen.getByText('Ethereum')).toBeInTheDocument(); - expect(screen.getByText('ETH')).toBeInTheDocument(); - expect(screen.getByText('1.2m')).toBeInTheDocument(); - expect(screen.getByText('$30,123')).toBeInTheDocument(); - expect(screen.getByText('$0.042188')).toBeInTheDocument(); - expect(screen.getByText('20.1%')).toBeInTheDocument(); - expect(screen.getByText('1823')).toBeInTheDocument(); - - expect(screen.getAllByText('XDAI')).toHaveLength(2); - expect(screen.getByText('1.4m')).toBeInTheDocument(); - expect(screen.getByText('$3,123')).toBeInTheDocument(); - expect(screen.getByText('$1.062188')).toBeInTheDocument(); - expect(screen.getByText('3.1%')).toBeInTheDocument(); - expect(screen.getByText('1423')).toBeInTheDocument(); + // Target the mobile layout otherwise it would not consider the hidden elements when in mobile or desktop + const mobileContainer = container.querySelector( + '.flex-col.desktop\\:hidden' + ) as HTMLElement; + expect(mobileContainer).toBeInTheDocument(); + + const mobileScreen = within(mobileContainer!); + + expect(mobileScreen.getByText('Ethereum')).toBeInTheDocument(); + expect(mobileScreen.getByText('ETH')).toBeInTheDocument(); + expect(mobileScreen.getByText('1.2m')).toBeInTheDocument(); + expect(mobileScreen.getByText('$30,123')).toBeInTheDocument(); + expect(mobileScreen.getByText('$0.042188')).toBeInTheDocument(); + expect(mobileScreen.getByText('20.1%')).toBeInTheDocument(); + expect(mobileScreen.getByText('1823')).toBeInTheDocument(); + + expect(mobileScreen.getAllByText('XDAI')).toHaveLength(2); + expect(mobileScreen.getByText('1.4m')).toBeInTheDocument(); + expect(mobileScreen.getByText('$3,123')).toBeInTheDocument(); + expect(mobileScreen.getByText('$1.062188')).toBeInTheDocument(); + expect(mobileScreen.getByText('3.1%')).toBeInTheDocument(); + expect(mobileScreen.getByText('1423')).toBeInTheDocument(); }); it('does not render anything while loading', () => { @@ -168,7 +176,7 @@ describe('', () => { expect(screen.queryByText('Top Tokens')).not.toBeInTheDocument(); }); - it('renders only up to 8 rows even if more are provided', () => { + it('renders the right number of rowsd', () => { const overfilledData: Projection = { ...mockTokensMarketData, data: { @@ -179,13 +187,21 @@ describe('', () => { }, }; - render( + const { container } = render( ); - const ethItems = screen.getAllByText('Ethereum'); - expect(ethItems.length).toBeLessThanOrEqual(8); + // Target the mobile layout otherwise it would not consider the hidden elements when in mobile or desktop + const mobileContainer = container.querySelector( + '.flex-col.desktop\\:hidden' + ) as HTMLElement; + expect(mobileContainer).toBeInTheDocument(); + + const mobileScreen = within(mobileContainer!); + + const ethItems = mobileScreen.getAllByText('Ethereum'); + expect(ethItems.length).toBeLessThanOrEqual(10); }); }); diff --git a/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap index 1872f216..14eeb11b 100644 --- a/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap +++ b/src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap @@ -29,15 +29,15 @@ exports[` renders and matches snapshot 1`] = ` />
renders and matches snapshot 1`] = `

- 0 - 1 + 01

renders and matches snapshot 1`] = `

- 1d ago + 2d ago

renders and matches snapshot 1`] = `

-
-
@@ -192,8 +187,7 @@ exports[` renders and matches snapshot 1`] = `

- 0 - 2 + 02

renders and matches snapshot 1`] = `

- 24h ago + 2d ago

renders and matches snapshot 1`] = `

-
+ class="hidden desktop:grid desktop:grid-cols-2 desktop:gap-x-14 desktop:gap-y-4 w-full" + > +
+
+
+

+ 01 +

+
+ token-logo +
+
+
+

+ ETH +

+

+ Ethereum +

+ copy-token-address +
+
+

+ 2d ago +

+

+ + Vol: + + + 1.2m +

+

+ + Liq: + + + $30,123 +

+
+
+
+
+
+
+

+ $0.042188 +

+
+ + + + +

+ 20.1% +

+
+
+

+ + Txs: + + + 1823 +

+
+
+
+
+
+

+ 02 +

+
+ token-logo +
+ logo +
+
+
+
+

+ XDAI +

+

+ XDAI +

+ copy-token-address +
+
+

+ 2d ago +

+

+ + Vol: + + + 1.4m +

+

+ + Liq: + + + $3,123 +

+
+
+
+
+
+
+

+ $1.062188 +

+
+ + + + +

+ 3.1% +

+
+
+

+ + Txs: + + + 1423 +

+
+
+
+
+
@@ -367,15 +654,15 @@ exports[` renders and matches snapshot 1`] = ` />
renders and matches snapshot 1`] = `

- 0 - 1 + 01

renders and matches snapshot 1`] = `

- 1d ago + 2d ago

renders and matches snapshot 1`] = `

-
-
@@ -530,8 +812,7 @@ exports[` renders and matches snapshot 1`] = `

- 0 - 2 + 02

renders and matches snapshot 1`] = `

- 24h ago + 2d ago

renders and matches snapshot 1`] = `

-
+ class="hidden desktop:grid desktop:grid-cols-2 desktop:gap-x-14 desktop:gap-y-4 w-full" + > +
+
+
+

+ 01 +

+
+ token-logo +
+
+
+

+ ETH +

+

+ Ethereum +

+ copy-token-address +
+
+

+ 2d ago +

+

+ + Vol: + + + 1.2m +

+

+ + Liq: + + + $30,123 +

+
+
+
+
+
+
+

+ $0.042188 +

+
+ + + + +

+ 20.1% +

+
+
+

+ + Txs: + + + 1823 +

+
+
+
+
+
+

+ 02 +

+
+ token-logo +
+ logo +
+
+
+
+

+ XDAI +

+

+ XDAI +

+ copy-token-address +
+
+

+ 2d ago +

+

+ + Vol: + + + 1.4m +

+

+ + Liq: + + + $3,123 +

+
+
+
+
+
+
+

+ $1.062188 +

+
+ + + + +

+ 3.1% +

+
+
+

+ + Txs: + + + 1423 +

+
+
+
+
+
, diff --git a/src/utils/common.ts b/src/utils/common.ts index def7bf73..6e194eb6 100644 --- a/src/utils/common.ts +++ b/src/utils/common.ts @@ -39,3 +39,19 @@ export const copyToClipboard = async (text: string, onSuccess?: () => void) => { export const convertDateToUnixTimestamp = (date: Date): number => Math.floor(date.getTime() / 1000); + +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'); +}; From d98dd0e6cc05994d118a687693ba64c9329e965c Mon Sep 17 00:00:00 2001 From: RanaBug Date: Thu, 24 Apr 2025 13:56:25 +0100 Subject: [PATCH 4/5] rename file for TileTitle --- .../components/TileTitle/{TitleTitle.tsx => TileTitle.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/apps/pillarx-app/components/TileTitle/{TitleTitle.tsx => TileTitle.tsx} (100%) diff --git a/src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx b/src/apps/pillarx-app/components/TileTitle/TileTitle.tsx similarity index 100% rename from src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx rename to src/apps/pillarx-app/components/TileTitle/TileTitle.tsx From d865c4d5877ea25d3fa703a8a309eefb5c9c3f02 Mon Sep 17 00:00:00 2001 From: RanaBug Date: Thu, 24 Apr 2025 14:03:53 +0100 Subject: [PATCH 5/5] rename file for TileTitle --- .../TokensWithMarketDataTile/TokensWithMarketDataTile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx b/src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx index db1d37b8..a8f66fd0 100644 --- a/src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx +++ b/src/apps/pillarx-app/components/TokensWithMarketDataTile/TokensWithMarketDataTile.tsx @@ -3,7 +3,7 @@ import { Projection, TokensMarketData } from '../../../../types/api'; // components import TileContainer from '../TileContainer/TileContainer'; -import TileTitle from '../TileTitle/TitleTitle'; +import TileTitle from '../TileTitle/TileTitle'; import TokenMarketDataRow from '../TokenMarketDataRow/TokenMarketDataRow'; type TokensWithMarketDataTileProps = {