diff --git a/src/apps/pillarx-app/components/HorizontalToken/HorizontalToken.tsx b/src/apps/pillarx-app/components/HorizontalToken/HorizontalToken.tsx index 74addde3..65116e6b 100644 --- a/src/apps/pillarx-app/components/HorizontalToken/HorizontalToken.tsx +++ b/src/apps/pillarx-app/components/HorizontalToken/HorizontalToken.tsx @@ -1,7 +1,5 @@ -// images -import defaultLogo from '../../images/logo-unknown.png'; - // components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; import TokensPercentage from '../TokensPercentage/TokensPercentage'; import Body from '../Typography/Body'; import BodySmall from '../Typography/BodySmall'; @@ -36,11 +34,17 @@ const HorizontalToken = ({ 0{tokenIndex} - token-logo + {tokenLogo ? ( + token-logo + ) : ( +
+ +
+ )}
{tokenSymbol && {tokenSymbol}} {tokenName && ( diff --git a/src/apps/pillarx-app/components/HorizontalToken/test/HorizontalToken.test.tsx b/src/apps/pillarx-app/components/HorizontalToken/test/HorizontalToken.test.tsx index 3c3db1ef..96650d44 100644 --- a/src/apps/pillarx-app/components/HorizontalToken/test/HorizontalToken.test.tsx +++ b/src/apps/pillarx-app/components/HorizontalToken/test/HorizontalToken.test.tsx @@ -3,9 +3,6 @@ import renderer, { ReactTestRendererJSON } from 'react-test-renderer'; // components import HorizontalToken from '../HorizontalToken'; -// images -import defaultLogo from '../../../images/logo-unknown.png'; - // Mock components jest.mock('../../Typography/BodySmall', () => 'BodySmall'); jest.mock('../../Typography/Body', () => 'Body'); @@ -66,7 +63,7 @@ describe('', () => { expect(imgProp.props.src).toBe(logo); }); - it('renders the default logo when logo is not provided', () => { + it('renders the default logo (random avatar) when logo is not provided', () => { const tree = renderer .create( ', () => { ) as ReactTestRendererJSON; const imgProp = divElement.children?.find( - (child) => typeof child === 'object' && child.type === 'img' + (child) => typeof child === 'object' && child.type === 'div' ) as ReactTestRendererJSON; expect(imgProp).not.toBeNull(); - expect(imgProp.type).toBe('img'); - expect(imgProp.props.src).toBe(defaultLogo); + expect(imgProp.type).toBe('div'); + expect(imgProp.props.className).toContain('overflow-hidden'); }); it('renders the token symbol and name correctly', () => { diff --git a/src/apps/pillarx-app/components/MediaGridCollection/DisplayCollectionImage.tsx b/src/apps/pillarx-app/components/MediaGridCollection/DisplayCollectionImage.tsx index c9284e7b..1001af69 100644 --- a/src/apps/pillarx-app/components/MediaGridCollection/DisplayCollectionImage.tsx +++ b/src/apps/pillarx-app/components/MediaGridCollection/DisplayCollectionImage.tsx @@ -1,20 +1,15 @@ -import Avatar from 'boring-avatars'; - -type AvatarVariantType = - | 'marble' - | 'beam' - | 'pixel' - | 'sunset' - | 'ring' - | 'bauhaus'; +// components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; type DisplayCollectionImageProps = { + name: string; image?: string; className: string; url?: string; }; const DisplayCollectionImage = ({ + name, image, className, url, @@ -26,18 +21,6 @@ const DisplayCollectionImage = ({ }; if (!image) { - const variants: AvatarVariantType[] = [ - 'marble', - 'beam', - 'pixel', - 'sunset', - 'ring', - 'bauhaus', - ]; - - const randomVariant: AvatarVariantType = - variants[Math.floor(Math.random() * variants.length)]; - return (
- +
); } diff --git a/src/apps/pillarx-app/components/MediaGridCollection/MediaGridCollection.tsx b/src/apps/pillarx-app/components/MediaGridCollection/MediaGridCollection.tsx index cce379b2..27aa0639 100644 --- a/src/apps/pillarx-app/components/MediaGridCollection/MediaGridCollection.tsx +++ b/src/apps/pillarx-app/components/MediaGridCollection/MediaGridCollection.tsx @@ -25,6 +25,7 @@ const MediaGridCollection = ({ gridData }: MediaGridCollectionProps) => { className={`flex h-full ${gridItems.length > 1 ? 'basis-[73%]' : 'w-full'}`} > {
{gridItems[1] && ( { )} {gridItems[2] && ( { )} {gridItems[3] && ( {
', () => { it('renders correctly and matches snapshot with image', () => { const tree = renderer .create( - + ) .toJSON(); expect(tree).toMatchSnapshot(); @@ -25,7 +29,9 @@ describe('', () => { it('renders correctly and matches snapshot without image', () => { const tree = renderer - .create() + .create( + + ) .toJSON(); expect(tree).toMatchSnapshot(); }); @@ -33,6 +39,7 @@ describe('', () => { it('renders image with correct attributes and handles click', () => { render( ', () => { it('renders Avatar when no image is provided and handles click', () => { render( ); - const avatar = screen.getByTestId('display-collection-avatar'); + const avatar = screen.getByTestId('random-avatar'); expect(avatar).toBeInTheDocument(); const div = screen.getByTestId('display-collection-image'); @@ -74,7 +82,11 @@ describe('', () => { it('does not render cursor-pointer class when no url is provided', () => { render( - + ); const img = screen.getByTestId('display-collection-image'); 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 0186c1f3..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 @@ -20,7 +20,7 @@ exports[` renders correctly and matches snapshot witho > renders correctly and matches snapshot witho mask="url(#:r0:)" > renders correctly and matches snapshot witho { const [t] = useTranslation(); + const accountAddress = useWalletAddress(); const { data: dataPortlioOverview } = data || {}; const dataWallet = dataPortlioOverview as WalletPortfolioData | undefined; const { realized: pnl24hRealized = 0, unrealized: pnl24hUnrealized = 0 } = @@ -40,7 +41,7 @@ const PortfolioOverview = ({ data, isDataLoading }: PortfolioOverviewProps) => { const allBlockchainsLogos = dataWallet?.assets - ?.map((asset) => (asset.asset.logo ? asset.asset.logo : DefaultLogo)) + ?.map((asset) => (asset.asset.logo ? asset.asset.logo : 'random-avatar')) .flat() || []; const numberOfBlockchains = @@ -82,7 +83,7 @@ const PortfolioOverview = ({ data, isDataLoading }: PortfolioOverviewProps) => { className="p-10 gap-20 tablet:p-5 mobile:p-0 mobile:bg-[#1F1D23] mobile:flex-col mobile:gap-4" >
- +
{t`title.totalBalance`}
diff --git a/src/apps/pillarx-app/components/PortfolioOverview/test/__snapshots__/PortfolioOverview.test.tsx.snap b/src/apps/pillarx-app/components/PortfolioOverview/test/__snapshots__/PortfolioOverview.test.tsx.snap index c34f5256..b59ae850 100644 --- a/src/apps/pillarx-app/components/PortfolioOverview/test/__snapshots__/PortfolioOverview.test.tsx.snap +++ b/src/apps/pillarx-app/components/PortfolioOverview/test/__snapshots__/PortfolioOverview.test.tsx.snap @@ -85,28 +85,85 @@ exports[` renders correctly and matches snapshot 1`] = ` className="desktop:flex tablet:flex mobile:hidden mb-[54px] gap-2.5 items-center" >
- profile-icon + + + + + + + + + + + + + + + + +

- wallet + 0x7F30 ... - dress + 5a347

{ + const variants: AvatarVariantType[] = [ + 'marble', + 'beam', + 'pixel', + 'sunset', + 'ring', + 'bauhaus', + ]; + + const randomVariant: AvatarVariantType = + variants[Math.floor(Math.random() * variants.length)]; + + const avatarVariant = () => { + if (isRandomVariant && !variant) { + return randomVariant; + } + if (variant) { + return variant as AvatarVariantType; + } + return 'marble'; + }; + + return ( + + ); +}; + +export default RandomAvatar; diff --git a/src/apps/pillarx-app/components/TokenInfoHorizontal/TokenInfoHorizontal.tsx b/src/apps/pillarx-app/components/TokenInfoHorizontal/TokenInfoHorizontal.tsx index b4c261c1..79522a91 100644 --- a/src/apps/pillarx-app/components/TokenInfoHorizontal/TokenInfoHorizontal.tsx +++ b/src/apps/pillarx-app/components/TokenInfoHorizontal/TokenInfoHorizontal.tsx @@ -1,4 +1,5 @@ -import defaultLogo from '../../images/logo-unknown.png'; +// components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; import TokensPercentage from '../TokensPercentage/TokensPercentage'; import Body from '../Typography/Body'; import BodySmall from '../Typography/BodySmall'; @@ -23,11 +24,17 @@ const TokenInfoHorizontal = ({ className="flex flex-col py-5 px-[22px] gap-1 w-[122px] h-auto items-center cursor-pointer tablet:w-[120px] mobile:w-[100px] mobile:px-3.5" onClick={onClick} > - token-logo + {logo ? ( + token-logo + ) : ( +
+ +
+ )} {tokenName && {tokenName}} {tokenValue && ( ${tokenValue.toFixed(4)} diff --git a/src/apps/pillarx-app/components/TokenInfoHorizontal/test/TokenInfoHorizontal.test.tsx b/src/apps/pillarx-app/components/TokenInfoHorizontal/test/TokenInfoHorizontal.test.tsx index 0a1b3549..0c882341 100644 --- a/src/apps/pillarx-app/components/TokenInfoHorizontal/test/TokenInfoHorizontal.test.tsx +++ b/src/apps/pillarx-app/components/TokenInfoHorizontal/test/TokenInfoHorizontal.test.tsx @@ -1,8 +1,5 @@ import renderer, { ReactTestRendererJSON } from 'react-test-renderer'; -// images -import defaultLogo from '../../../images/logo-unknown.png'; - // components import TokenInfoHorizontal from '../TokenInfoHorizontal'; @@ -48,7 +45,7 @@ describe('', () => { expect(logoProp.props.src).toBe(logo); }); - it('renders the default logo when logo is not provided', () => { + it('renders the default logo (random avatar) when logo is not provided', () => { const tree = renderer .create( ', () => { .toJSON() as ReactTestRendererJSON; const logoProp = (tree.children?.find( - (child) => typeof child === 'object' && child.type === 'img' + (child) => typeof child === 'object' && child.type === 'div' ) as ReactTestRendererJSON) || null; expect(logoProp).not.toBeNull(); - expect(logoProp.type).toBe('img'); - expect(logoProp.props.src).toBe(defaultLogo); + expect(logoProp.type).toBe('div'); + expect(logoProp.props.className).toContain('overflow-hidden'); }); it('renders the token name correctly', () => { diff --git a/src/apps/pillarx-app/components/TokensHorizontalList/TokensHorizontalList.tsx b/src/apps/pillarx-app/components/TokensHorizontalList/TokensHorizontalList.tsx index a5734805..81003477 100644 --- a/src/apps/pillarx-app/components/TokensHorizontalList/TokensHorizontalList.tsx +++ b/src/apps/pillarx-app/components/TokensHorizontalList/TokensHorizontalList.tsx @@ -1,11 +1,12 @@ import { createRef, useEffect, useState } from 'react'; -// components -import Body from '../Typography/Body'; - // hooks import useRefDimensions from '../../hooks/useRefDimensions'; +// components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; +import Body from '../Typography/Body'; + type TokensHorizontalListProps = { logos: string[]; }; @@ -46,14 +47,23 @@ const TokensHorizontalList = ({ logos }: TokensHorizontalListProps) => { className="w-full h-fit flex justify-end" data-testid="tokens-list" > - {logos.slice(0, numberLogos).map((logo, index) => ( - token-logo - ))} + {logos.slice(0, numberLogos).map((logo, index) => + logo === 'random-avatar' ? ( +
+ +
+ ) : ( + token-logo + ) + )} {numberHiddenLogos > 0 && (
+ {numberHiddenLogos} diff --git a/src/apps/pillarx-app/components/WalletAdddressOverview/WalletAddressOverview.tsx b/src/apps/pillarx-app/components/WalletAdddressOverview/WalletAddressOverview.tsx index bfdea38f..52d64295 100644 --- a/src/apps/pillarx-app/components/WalletAdddressOverview/WalletAddressOverview.tsx +++ b/src/apps/pillarx-app/components/WalletAdddressOverview/WalletAddressOverview.tsx @@ -6,7 +6,7 @@ import { MdCheck } from 'react-icons/md'; // components import CopyIcon from '../../images/copy-icon.svg'; -import ProfileIcon from '../../images/profile-icon.svg'; +import RandomAvatar from '../RandomAvatar/RandomAvatar'; import Body from '../Typography/Body'; type WalletAddressOverviewProps = { @@ -30,8 +30,8 @@ const WalletAddressOverview = ({ address }: WalletAddressOverviewProps) => { return (
-
- profile-icon +
+
{address.substring(0, 6)}...{address.substring(address.length - 5)} diff --git a/src/apps/pillarx-app/components/WalletAdddressOverview/test/__snapshots__/WalletAddressOverview.test.tsx.snap b/src/apps/pillarx-app/components/WalletAdddressOverview/test/__snapshots__/WalletAddressOverview.test.tsx.snap index 8ba680eb..14b714b1 100644 --- a/src/apps/pillarx-app/components/WalletAdddressOverview/test/__snapshots__/WalletAddressOverview.test.tsx.snap +++ b/src/apps/pillarx-app/components/WalletAdddressOverview/test/__snapshots__/WalletAddressOverview.test.tsx.snap @@ -5,21 +5,78 @@ exports[` renders correctly and matches snapshot 1`] = className="desktop:flex tablet:flex mobile:hidden mb-[54px] gap-2.5 items-center" >
- profile-icon + + + + + + + + + + + + + + + + +

renders correctly and matches snapshot 1`] = ` chain-logo

@@ -129,7 +128,6 @@ exports[` renders correctly and matches snapshot 1`] = ` chain-logo
diff --git a/src/apps/the-exchange/components/DropdownTokensList/test/__snapshots__/DropdownTokensList.test.tsx.snap b/src/apps/the-exchange/components/DropdownTokensList/test/__snapshots__/DropdownTokensList.test.tsx.snap index 6e823878..24bb44e9 100644 --- a/src/apps/the-exchange/components/DropdownTokensList/test/__snapshots__/DropdownTokensList.test.tsx.snap +++ b/src/apps/the-exchange/components/DropdownTokensList/test/__snapshots__/DropdownTokensList.test.tsx.snap @@ -94,7 +94,6 @@ exports[` renders correctly and matches snapshot 1`] = ` chain-logo
diff --git a/src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx b/src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx index d76e1b29..a034c56f 100644 --- a/src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx +++ b/src/apps/the-exchange/components/ExchangeAction/ExchangeAction.tsx @@ -162,7 +162,11 @@ const ExchangeAction = () => { )}
- + {receiveToken?.symbol ?? ''}
diff --git a/src/apps/the-exchange/components/ExchangeAction/test/__snapshots__/ExchangeAction.test.tsx.snap b/src/apps/the-exchange/components/ExchangeAction/test/__snapshots__/ExchangeAction.test.tsx.snap index 8dd85a2b..29e505eb 100644 --- a/src/apps/the-exchange/components/ExchangeAction/test/__snapshots__/ExchangeAction.test.tsx.snap +++ b/src/apps/the-exchange/components/ExchangeAction/test/__snapshots__/ExchangeAction.test.tsx.snap @@ -38,7 +38,6 @@ exports[` renders correctly and matches snapshot 1`] = ` chain-logo
diff --git a/src/apps/the-exchange/components/RandomAvatar/RandomAvatar.tsx b/src/apps/the-exchange/components/RandomAvatar/RandomAvatar.tsx new file mode 100644 index 00000000..3388dc87 --- /dev/null +++ b/src/apps/the-exchange/components/RandomAvatar/RandomAvatar.tsx @@ -0,0 +1,48 @@ +import Avatar from 'boring-avatars'; +import { AvatarVariantType } from '../../../../types'; + +type RandomAvatarProps = { + name: string; + variant?: string; + isRandomVariant?: boolean; +}; + +const RandomAvatar = ({ + name, + variant, + isRandomVariant, +}: RandomAvatarProps) => { + const variants: AvatarVariantType[] = [ + 'marble', + 'beam', + 'pixel', + 'sunset', + 'ring', + 'bauhaus', + ]; + + const randomVariant: AvatarVariantType = + variants[Math.floor(Math.random() * variants.length)]; + + const avatarVariant = () => { + if (isRandomVariant && !variant) { + return randomVariant; + } + if (variant) { + return variant as AvatarVariantType; + } + return 'marble'; + }; + + return ( + + ); +}; + +export default RandomAvatar; diff --git a/src/apps/the-exchange/components/SelectToken/SelectToken.tsx b/src/apps/the-exchange/components/SelectToken/SelectToken.tsx index b8c88dcf..5bc1b359 100644 --- a/src/apps/the-exchange/components/SelectToken/SelectToken.tsx +++ b/src/apps/the-exchange/components/SelectToken/SelectToken.tsx @@ -41,7 +41,11 @@ const SelectToken = ({ : 'Select Token'} - {tokenLogo && } + ); }; diff --git a/src/apps/the-exchange/components/SelectToken/test/__snapshots__/SelectToken.test.tsx.snap b/src/apps/the-exchange/components/SelectToken/test/__snapshots__/SelectToken.test.tsx.snap index 0ffae5c1..9b3115f1 100644 --- a/src/apps/the-exchange/components/SelectToken/test/__snapshots__/SelectToken.test.tsx.snap +++ b/src/apps/the-exchange/components/SelectToken/test/__snapshots__/SelectToken.test.tsx.snap @@ -34,7 +34,6 @@ exports[` renders correctly and matches snapshot 1`] = ` chain-logo diff --git a/src/apps/the-exchange/components/TokenListItem/TokenListItem.tsx b/src/apps/the-exchange/components/TokenListItem/TokenListItem.tsx index e40a8e87..7e84aa29 100644 --- a/src/apps/the-exchange/components/TokenListItem/TokenListItem.tsx +++ b/src/apps/the-exchange/components/TokenListItem/TokenListItem.tsx @@ -26,7 +26,12 @@ const TokenListItem = ({ data-testid="token-list-item" >
- +
{tokenName} diff --git a/src/apps/the-exchange/components/TokenListItem/test/TokenListItem.test.tsx b/src/apps/the-exchange/components/TokenListItem/test/TokenListItem.test.tsx index fb75c5bc..fe2add47 100644 --- a/src/apps/the-exchange/components/TokenListItem/test/TokenListItem.test.tsx +++ b/src/apps/the-exchange/components/TokenListItem/test/TokenListItem.test.tsx @@ -43,7 +43,7 @@ describe('', () => { expect(screen.getByAltText('token-logo')).toHaveAttribute('src', tokenLogo); }); - it('renders TokenListItem with default logo when no tokenLogo is provided', () => { + it('renders TokenListItem with default logo (random avatar) when no tokenLogo is provided', () => { render( ', () => { /> ); - const defaultLogo = screen.getByAltText('token-logo'); - expect(defaultLogo).toHaveAttribute( - 'src', - expect.stringContaining('logo-unknown.png') - ); + const defaultLogo = screen.getByTestId('random-avatar'); + expect(defaultLogo).toBeInTheDocument(); }); it('calls onClick when TokenListItem is clicked', () => { diff --git a/src/apps/the-exchange/components/TokenListItem/test/__snapshots__/TokenListItem.test.tsx.snap b/src/apps/the-exchange/components/TokenListItem/test/__snapshots__/TokenListItem.test.tsx.snap index bde338ac..3bdd3778 100644 --- a/src/apps/the-exchange/components/TokenListItem/test/__snapshots__/TokenListItem.test.tsx.snap +++ b/src/apps/the-exchange/components/TokenListItem/test/__snapshots__/TokenListItem.test.tsx.snap @@ -24,7 +24,6 @@ exports[` renders correctly and matches snapshot 1`] = ` chain-logo
diff --git a/src/apps/the-exchange/components/TokenLogo/TokenLogo.tsx b/src/apps/the-exchange/components/TokenLogo/TokenLogo.tsx index 200d9c7b..8161d040 100644 --- a/src/apps/the-exchange/components/TokenLogo/TokenLogo.tsx +++ b/src/apps/the-exchange/components/TokenLogo/TokenLogo.tsx @@ -1,25 +1,44 @@ -// images -import DefaultLogo from '../../images/logo-unknown.png'; +// components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; type TokenLogoProps = { + tokenName?: string; tokenLogo?: string; tokenChainLogo?: string; isBigger?: boolean; + showLogo?: boolean; }; -const TokenLogo = ({ tokenLogo, tokenChainLogo, isBigger }: TokenLogoProps) => { +const TokenLogo = ({ + tokenName, + tokenLogo, + tokenChainLogo, + isBigger, + showLogo, +}: TokenLogoProps) => { + if (!showLogo) return null; + return (
- token-logo + {tokenLogo ? ( + token-logo + ) : ( +
+ +
+ )} +
chain-logo diff --git a/src/apps/the-exchange/components/TokenLogo/test/TokenLogo.test.tsx b/src/apps/the-exchange/components/TokenLogo/test/TokenLogo.test.tsx index 09d02ad5..59cc33ce 100644 --- a/src/apps/the-exchange/components/TokenLogo/test/TokenLogo.test.tsx +++ b/src/apps/the-exchange/components/TokenLogo/test/TokenLogo.test.tsx @@ -5,9 +5,6 @@ import renderer from 'react-test-renderer'; // components import TokenLogo from '../TokenLogo'; // Assuming the path is correct -// images -import DefaultLogo from '../../../images/logo-unknown.png'; - describe('', () => { const tokenLogo = 'https://example.com/token-logo.png'; const tokenChainLogo = 'https://example.com/token-chain-logo.png'; @@ -15,38 +12,39 @@ describe('', () => { it('renders correctly and matches snapshot', () => { const tree = renderer .create( - + ) .toJSON(); expect(tree).toMatchSnapshot(); }); it('renders the token logo', () => { - render(); + render(); const tokenLogo = screen.getByAltText('token-logo'); + const defaultLogo = screen.queryByTestId('random-avatar'); + expect(tokenLogo).toHaveAttribute('src', 'token-logo.png'); + expect(defaultLogo).not.toBeInTheDocument(); }); - it('renders the default token logo when no token logo is provided', () => { - render(); - const tokenLogo = screen.getByAltText('token-logo'); - expect(tokenLogo).toHaveAttribute('src', DefaultLogo); + it('renders the default token logo (random avatar) when no token logo is provided', () => { + render(); + const tokenLogo = screen.getByTestId('random-avatar'); + expect(tokenLogo).toBeInTheDocument(); }); it('renders the token chain logo', () => { - render(); + render(); const tokenChainLogo = screen.getByAltText('chain-logo'); expect(tokenChainLogo).toHaveAttribute('src', 'token-chain-logo.png'); }); - it('renders the default token chain logo when no token chain logo is provided', () => { - render(); - const tokenChainLogo = screen.getByAltText('chain-logo'); - expect(tokenChainLogo).toHaveAttribute('src', DefaultLogo); - }); - it('applies the correct classes when isBigger is true', () => { - render(); + render(); const tokenLogo = screen.getByAltText('token-logo'); const tokenChainLogo = screen.getByAltText('chain-logo'); expect(tokenLogo).toHaveClass('w-[30px] h-[30px]'); @@ -54,7 +52,7 @@ describe('', () => { }); it('applies the correct classes when isBigger is false', () => { - render(); + render(); const tokenLogo = screen.getByAltText('token-logo'); const tokenChainLogo = screen.getByAltText('chain-logo'); expect(tokenLogo).toHaveClass('w-5 h-5'); diff --git a/src/apps/token-atlas/components/ChainCard/ChainCard.tsx b/src/apps/token-atlas/components/ChainCard/ChainCard.tsx index 7a05ab8e..b30db5b6 100644 --- a/src/apps/token-atlas/components/ChainCard/ChainCard.tsx +++ b/src/apps/token-atlas/components/ChainCard/ChainCard.tsx @@ -10,6 +10,7 @@ import { setBlockchainList } from '../../reducer/tokenAtlasSlice'; import { useAppDispatch } from '../../hooks/useReducerHooks'; // components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; import Body from '../Typography/Body'; type ChainCardProps = { @@ -45,12 +46,16 @@ const ChainCard = ({ chainName }: ChainCardProps) => { explorerLink && 'cursor-pointer' }`} > - {blockchainLogo && ( + {blockchainLogo ? ( chain-logo + ) : ( +
+ +
)} {chainName}
diff --git a/src/apps/token-atlas/components/RandomAvatar/RandomAvatar.tsx b/src/apps/token-atlas/components/RandomAvatar/RandomAvatar.tsx new file mode 100644 index 00000000..3388dc87 --- /dev/null +++ b/src/apps/token-atlas/components/RandomAvatar/RandomAvatar.tsx @@ -0,0 +1,48 @@ +import Avatar from 'boring-avatars'; +import { AvatarVariantType } from '../../../../types'; + +type RandomAvatarProps = { + name: string; + variant?: string; + isRandomVariant?: boolean; +}; + +const RandomAvatar = ({ + name, + variant, + isRandomVariant, +}: RandomAvatarProps) => { + const variants: AvatarVariantType[] = [ + 'marble', + 'beam', + 'pixel', + 'sunset', + 'ring', + 'bauhaus', + ]; + + const randomVariant: AvatarVariantType = + variants[Math.floor(Math.random() * variants.length)]; + + const avatarVariant = () => { + if (isRandomVariant && !variant) { + return randomVariant; + } + if (variant) { + return variant as AvatarVariantType; + } + return 'marble'; + }; + + return ( + + ); +}; + +export default RandomAvatar; diff --git a/src/apps/token-atlas/components/TokenCard/TokenCard.tsx b/src/apps/token-atlas/components/TokenCard/TokenCard.tsx index 54364ba7..a9d3f8c0 100644 --- a/src/apps/token-atlas/components/TokenCard/TokenCard.tsx +++ b/src/apps/token-atlas/components/TokenCard/TokenCard.tsx @@ -1,4 +1,5 @@ // components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; import Body from '../Typography/Body'; type TokenCardProps = { @@ -23,21 +24,29 @@ const TokenCard = ({ onClick={onClick} data-testid="token-card" > - {blockchainLogo && ( + {blockchainLogo ? ( chain-logo + ) : ( +
+ +
)} - {tokenLogo && ( + {tokenLogo ? ( token-logo + ) : ( +
+ +
)} {tokenName} diff --git a/src/apps/token-atlas/components/TokenCard/test/TokenCard.test.tsx b/src/apps/token-atlas/components/TokenCard/test/TokenCard.test.tsx index dfdb0dc9..9c9ff84c 100644 --- a/src/apps/token-atlas/components/TokenCard/test/TokenCard.test.tsx +++ b/src/apps/token-atlas/components/TokenCard/test/TokenCard.test.tsx @@ -38,7 +38,7 @@ describe('', () => { expect(screen.getByText('TTK')).toBeInTheDocument(); }); - it('renders without tokenLogo and blockchainLogo', () => { + it('renders with default tokenLogo and default blockchainLogo (random avatar)', () => { const propsWithoutLogos = { tokenName: undefined, tokenSymbol: undefined, @@ -55,6 +55,7 @@ describe('', () => { ).not.toBeInTheDocument(); expect(screen.queryByText('Test Token')).not.toBeInTheDocument(); expect(screen.queryByText('TTK')).not.toBeInTheDocument(); + expect(screen.getAllByTestId('random-avatar')).toHaveLength(2); }); it('calls onClick when clicked', () => { diff --git a/src/apps/token-atlas/components/TokenGraphColumn/TokenGraphColumn.tsx b/src/apps/token-atlas/components/TokenGraphColumn/TokenGraphColumn.tsx index d63d8eb6..6f8b22d3 100644 --- a/src/apps/token-atlas/components/TokenGraphColumn/TokenGraphColumn.tsx +++ b/src/apps/token-atlas/components/TokenGraphColumn/TokenGraphColumn.tsx @@ -28,6 +28,7 @@ import ArrowRed from '../../images/arrow-circle-red.svg'; // components import SkeletonLoader from '../../../../components/SkeletonLoader'; +import RandomAvatar from '../RandomAvatar/RandomAvatar'; import TokenGraph from '../TokenGraph/TokenGraph'; import Body from '../Typography/Body'; @@ -133,13 +134,17 @@ const TokenGraphColumn = ({ ) : ( <> - {tokenDataInfo?.logo && ( + {tokenDataInfo?.logo ? ( token-logo + ) : ( +
+ +
)} {tokenDataInfo ? tokenDataInfo.name : 'Token not found'} diff --git a/src/apps/token-atlas/components/TokenInfoColumn/test/__snapshots__/TokenInfoColumn.test.tsx.snap b/src/apps/token-atlas/components/TokenInfoColumn/test/__snapshots__/TokenInfoColumn.test.tsx.snap index 72673c57..a9363e5e 100644 --- a/src/apps/token-atlas/components/TokenInfoColumn/test/__snapshots__/TokenInfoColumn.test.tsx.snap +++ b/src/apps/token-atlas/components/TokenInfoColumn/test/__snapshots__/TokenInfoColumn.test.tsx.snap @@ -25,6 +25,80 @@ exports[` renders correctly and matches snapshot 1`] = ` className="flex rounded-[50px] bg-medium_grey p-1 pr-3 items-center h-8 max-w-[150px] undefined" id="token-atlas-chain-card" > +
+ + + + + + + + + + + + + + + + + +

@@ -40,6 +114,80 @@ exports[` renders correctly and matches snapshot 1`] = ` className="flex rounded-[50px] bg-medium_grey p-1 pr-3 items-center h-8 max-w-[150px] undefined" id="token-atlas-chain-card" > +

+ + + + + + + + + + + + + + + + + +

@@ -55,6 +203,80 @@ exports[` renders correctly and matches snapshot 1`] = ` className="flex rounded-[50px] bg-medium_grey p-1 pr-3 items-center h-8 max-w-[150px] undefined" id="token-atlas-chain-card" > +

+ + + + + + + + + + + + + + + + + +

diff --git a/src/apps/token-atlas/components/TokenResultCard/TokenResultCard.tsx b/src/apps/token-atlas/components/TokenResultCard/TokenResultCard.tsx index bb9d51c9..d1cf0853 100644 --- a/src/apps/token-atlas/components/TokenResultCard/TokenResultCard.tsx +++ b/src/apps/token-atlas/components/TokenResultCard/TokenResultCard.tsx @@ -1,6 +1,9 @@ -// images +// utils import { convertChainIdtoName } from '../../utils/converters'; +// components +import RandomAvatar from '../RandomAvatar/RandomAvatar'; + // components import Body from '../Typography/Body'; @@ -27,12 +30,16 @@ const TokenResultCard = ({ data-testid="token-result-card" >

- {tokenLogo && ( + {tokenLogo ? ( token-logo + ) : ( +
+ +
)}
{tokenName && ( diff --git a/src/apps/token-atlas/components/TokenResultCard/test/TokenResultCard.test.tsx b/src/apps/token-atlas/components/TokenResultCard/test/TokenResultCard.test.tsx index 0e37209b..7d9b6a98 100644 --- a/src/apps/token-atlas/components/TokenResultCard/test/TokenResultCard.test.tsx +++ b/src/apps/token-atlas/components/TokenResultCard/test/TokenResultCard.test.tsx @@ -88,13 +88,13 @@ describe('', () => { expect(logo).toHaveAttribute('src', mockTokenLogo); }); - it('does not display token name, symbol, chain, or logo when not provided', () => { + it('does not display token name, symbol, chain but display default logo when not provided', () => { render(); expect(screen.queryByText(mockTokenName)).not.toBeInTheDocument(); expect(screen.queryByText(mockTokenSymbol)).not.toBeInTheDocument(); expect(screen.queryByText('On Ethereum')).not.toBeInTheDocument(); - expect(screen.queryByRole('img')).not.toBeInTheDocument(); + expect(screen.getByTestId('random-avatar')).toBeInTheDocument(); }); it('handles click events correctly', () => { diff --git a/src/components/BottomMenuModal/AccountModal.tsx b/src/components/BottomMenuModal/AccountModal.tsx index 2cbab304..ee6773b1 100644 --- a/src/components/BottomMenuModal/AccountModal.tsx +++ b/src/components/BottomMenuModal/AccountModal.tsx @@ -18,7 +18,6 @@ import { Gallery as IconGallery, Hierarchy as IconHierarchy, Logout as LogoutIcon, - User as UserIcon, } from 'iconsax-react'; import React, { useCallback, useContext, useEffect, useMemo } from 'react'; import CopyToClipboard from 'react-copy-to-clipboard'; @@ -28,6 +27,7 @@ import styled, { useTheme } from 'styled-components'; import { Chain } from 'viem'; // components +import RandomAvatar from '../../apps/pillarx-app/components/RandomAvatar/RandomAvatar'; import FormTabSelect from '../Form/FormTabSelect'; import ImageWithFallback from '../ImageWithFallback'; import SkeletonLoader from '../SkeletonLoader'; @@ -194,7 +194,9 @@ const AccountModal = ({ isContentVisible }: AccountModalProps) => { - +
+ +
{truncateAddress(accountAddress, 14)} diff --git a/src/types/index.ts b/src/types/index.ts index 0b2f206c..f61718c6 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -26,3 +26,11 @@ export interface SendModalDataBase { description?: string; onSent?: (userOpHashes: string[]) => void; } + +export type AvatarVariantType = + | 'marble' + | 'beam' + | 'pixel' + | 'sunset' + | 'ring' + | 'bauhaus';