Skip to content

Commit 9775c81

Browse files
Change home screen styling
1 parent 0644340 commit 9775c81

File tree

9 files changed

+445
-260
lines changed

9 files changed

+445
-260
lines changed

packages/app/components/TopNav.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ export function TopNav({
162162
)
163163
case media.gtLg && !showOnGtLg:
164164
return null
165-
case Boolean(queryParams.token):
165+
case queryParams.token !== undefined:
166166
return (
167167
<XStack ai="center" f={1}>
168168
<Button onPress={handleBack}>
@@ -174,6 +174,18 @@ export function TopNav({
174174
/>
175175
</ButtonOg.Icon>
176176
</Button>
177+
<Paragraph size={'$8'} col={'$color10'}>
178+
{(() => {
179+
switch (queryParams.token) {
180+
case 'investments':
181+
return 'Invest'
182+
case 'stables':
183+
return 'Cash'
184+
default:
185+
return 'Balance'
186+
}
187+
})()}
188+
</Paragraph>
177189
</XStack>
178190
)
179191
case !isSubRoute:

packages/app/data/coins.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export const allCoinsDict = allCoins.reduce((acc, coin) => {
198198

199199
export type allCoinsDict = typeof allCoinsDict
200200

201-
export type CoinWithBalance = allCoins[number] & {
201+
export type CoinWithBalance = coin & {
202202
balance: bigint | undefined
203203
}
204204

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Card, type CardProps, Paragraph, XStack } from '@my/ui'
2+
3+
import { ChevronRight } from '@tamagui/lucide-icons'
4+
import { type LinkProps, useLink } from 'solito/link'
5+
6+
export const FriendsCard = ({ href, ...props }: Omit<CardProps & LinkProps, 'children'>) => {
7+
const linkProps = useLink({ href })
8+
9+
return (
10+
<Card
11+
elevate
12+
hoverStyle={{ scale: 0.925 }}
13+
pressStyle={{ scale: 0.875 }}
14+
animation="bouncy"
15+
size={'$5'}
16+
br="$7"
17+
{...linkProps}
18+
{...props}
19+
>
20+
<Card.Header padded fd="row" ai="center" jc="space-between">
21+
<Paragraph fontSize={'$7'} fontWeight="400">
22+
Friends
23+
</Paragraph>
24+
<XStack flex={1} />
25+
<ChevronRight
26+
size={'$1.5'}
27+
color={'$lightGrayTextField'}
28+
$theme-light={{ color: '$darkGrayTextField' }}
29+
/>
30+
</Card.Header>
31+
<Card.Footer padded />
32+
</Card>
33+
)
34+
}

packages/app/features/home/InvestmentBalanceList.tsx

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
import { Link, LinkableButton, type LinkProps, Paragraph, XStack, YStack } from '@my/ui'
2-
1+
import { Link, type LinkProps, Paragraph, XStack, YStack } from '@my/ui'
32
import { IconCoin } from 'app/components/icons/IconCoin'
43
import type { CoinWithBalance } from 'app/data/coins'
54

6-
import { useCoins } from 'app/provider/coins'
7-
85
import formatAmount from 'app/utils/formatAmount'
96
import { Fragment } from 'react'
107
import { useHoverStyles } from 'app/utils/useHoverStyles'
@@ -13,17 +10,17 @@ import { useTokenPrices } from 'app/utils/useTokenPrices'
1310
import { type MarketData, useMultipleTokensMarketData } from 'app/utils/coin-gecko'
1411
import { useThemeSetting } from '@tamagui/next-theme'
1512
import { useIsPriceHidden } from 'app/features/home/utils/useIsPriceHidden'
16-
import { IconPlus } from 'app/components/icons'
1713

18-
export const InvestmentsBalanceList = () => {
19-
const { investmentCoins, isLoading } = useCoins()
14+
export const InvestmentsBalanceList = ({
15+
coins,
16+
}: {
17+
coins: CoinWithBalance[]
18+
}) => {
2019
const hoverStyles = useHoverStyles()
2120
const { data: tokensMarketData, isLoading: isLoadingTokensMarketData } =
22-
useMultipleTokensMarketData(investmentCoins?.map((c) => c.coingeckoTokenId) || [])
23-
24-
if (isLoading) return null
21+
useMultipleTokensMarketData(coins?.map((c) => c.coingeckoTokenId) || [])
2522

26-
return investmentCoins.map((coin) => (
23+
return coins.map((coin) => (
2724
<Fragment key={`token-balance-list-${coin.label}`}>
2825
<TokenBalanceItem
2926
testID={`token-balance-list-${coin.label}`}
@@ -75,7 +72,7 @@ const TokenBalanceItem = ({
7572
<YStack f={1} jc={'space-between'}>
7673
<XStack jc={'space-between'} ai={'center'}>
7774
<Paragraph fontSize={'$6'} fontWeight={'500'} color={'$color12'}>
78-
{coin.shortLabel || coin.label}
75+
{coin.label}
7976
</Paragraph>
8077
<TokenBalance coin={coin} />
8178
</XStack>
@@ -128,27 +125,10 @@ const TokenBalance = ({
128125

129126
if (balance === undefined) return <></>
130127
return (
131-
<Paragraph
132-
fontSize={'$6'}
133-
fontWeight={'500'}
134-
col="$color12"
135-
$gtSm={{ fontSize: '$8', fontWeight: '600' }}
136-
>
128+
<Paragraph fontSize={'$8'} fontWeight={'500'} col="$color12">
137129
{isPriceHidden
138130
? '//////'
139131
: formatAmount((Number(balance) / 10 ** decimals).toString(), 10, formatDecimals ?? 5)}
140132
</Paragraph>
141133
)
142134
}
143-
144-
export const AddInvestmentLink = () => {
145-
const hoverStyles = useHoverStyles()
146-
147-
return (
148-
<LinkableButton circular href="/trade" p="$2" size="$5" hoverStyle={hoverStyles}>
149-
<LinkableButton.Icon>
150-
<IconPlus size="$5" color="$color10" />
151-
</LinkableButton.Icon>
152-
</LinkableButton>
153-
)
154-
}

packages/app/features/home/InvestmentsBalanceCard.tsx

Lines changed: 111 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
1-
import { Button, Card, Paragraph, Spinner, Theme, XStack, YStack } from '@my/ui'
1+
import {
2+
Card,
3+
type CardProps,
4+
H1,
5+
Paragraph,
6+
Spinner,
7+
Theme,
8+
useMedia,
9+
XStack,
10+
type XStackProps,
11+
} from '@my/ui'
212
import formatAmount from 'app/utils/formatAmount'
313

414
import { ChevronLeft, ChevronRight } from '@tamagui/lucide-icons'
515

616
import { useIsPriceHidden } from './utils/useIsPriceHidden'
717

818
import { useSendAccountBalances } from 'app/utils/useSendAccountBalances'
9-
import { investmentCoins } from 'app/data/coins'
19+
import { type CoinWithBalance, investmentCoins } from 'app/data/coins'
1020

1121
import { useRootScreenParams } from 'app/routers/params'
1222
import { useMultipleTokensMarketData } from 'app/utils/coin-gecko'
1323
import { useMemo } from 'react'
14-
import { IconError } from 'app/components/icons'
24+
import { IconCoin, IconError } from 'app/components/icons'
1525
import { useCoins } from 'app/provider/coins'
26+
import { investmentCoins as investmentCoinsList } from 'app/data/coins'
1627

17-
export const InvestmentsBalanceCard = () => {
28+
export const InvestmentsBalanceCard = (props: CardProps) => {
29+
const media = useMedia()
1830
const [queryParams, setParams] = useRootScreenParams()
1931
const isInvestmentCoin = investmentCoins.some(
20-
(coin) => coin.token.toLowerCase() === queryParams.token
32+
(coin) => coin.token.toLowerCase() === queryParams.token?.toLowerCase()
2133
)
2234
const isInvestmentsScreen = queryParams.token === 'investments'
2335

@@ -39,62 +51,105 @@ export const InvestmentsBalanceCard = () => {
3951
const formattedBalance = formatAmount(dollarTotal, 9, 0)
4052

4153
return (
42-
<Card py="$5" px="$4" w={'100%'} jc="space-between" onPress={toggleSubScreen}>
43-
<YStack jc={'center'} gap={'$5'} w={'100%'}>
44-
<YStack w={'100%'} gap={'$2.5'} jc="space-between">
45-
<XStack ai={'center'} jc={'space-between'} gap="$2.5" width={'100%'}>
46-
<Paragraph fontSize={'$7'} fontWeight="400">
47-
Invest
48-
</Paragraph>
49-
<Button
50-
chromeless
51-
backgroundColor="transparent"
52-
hoverStyle={{ backgroundColor: 'transparent' }}
53-
pressStyle={{
54-
backgroundColor: 'transparent',
55-
borderColor: 'transparent',
56-
}}
57-
focusStyle={{ backgroundColor: 'transparent' }}
58-
p={0}
59-
height={'auto'}
60-
>
61-
<Button.Icon>
62-
{isInvestmentCoin || isInvestmentsScreen ? (
63-
<ChevronLeft
64-
size={'$1.5'}
65-
color={'$lightGrayTextField'}
66-
$theme-light={{ color: '$darkGrayTextField' }}
67-
$lg={{ display: 'none' }}
68-
/>
69-
) : (
70-
<ChevronRight
71-
size={'$1.5'}
72-
color={'$primary'}
73-
$theme-light={{ color: '$color12' }}
74-
/>
75-
)}
76-
</Button.Icon>
77-
</Button>
78-
</XStack>
79-
</YStack>
80-
<Paragraph fontSize={'$10'} fontWeight={'600'} color={'$color12'}>
81-
{(() => {
82-
switch (true) {
83-
case isPriceHidden:
84-
return '///////'
85-
case isLoading || !dollarBalances:
86-
return <Spinner size={'large'} />
87-
default:
88-
return `$${formattedBalance}`
89-
}
90-
})()}
54+
<Card
55+
elevate
56+
hoverStyle={{ scale: 0.925 }}
57+
pressStyle={{ scale: 0.875 }}
58+
animation="bouncy"
59+
onPress={toggleSubScreen}
60+
size={'$5'}
61+
br="$7"
62+
w="100%"
63+
{...props}
64+
>
65+
<Card.Header padded pb={0} fd="row" ai="center" jc="space-between">
66+
<Paragraph fontSize={'$5'} fontWeight="400">
67+
Invest
9168
</Paragraph>
92-
<InvestmentsAggregate />
93-
</YStack>
69+
{isInvestmentCoin || isInvestmentsScreen ? (
70+
<ChevronLeft
71+
size={'$1'}
72+
color={'$primary'}
73+
$theme-light={{ color: '$color12' }}
74+
$lg={{ display: 'none' }}
75+
/>
76+
) : (
77+
<ChevronRight
78+
size={'$1'}
79+
color={'$lightGrayTextField'}
80+
$theme-light={{ color: '$darkGrayTextField' }}
81+
/>
82+
)}
83+
</Card.Header>
84+
<Card.Footer padded fd="column" gap="$2">
85+
{isInvestmentsScreen && !media.gtLg ? (
86+
<>
87+
<Paragraph color={'$color12'} fontWeight={500} size={'$10'}>
88+
{(() => {
89+
switch (true) {
90+
case isPriceHidden:
91+
return '///////'
92+
case isLoading || !dollarBalances:
93+
return <Spinner size={'large'} color={'$color12'} />
94+
default:
95+
return `$${formattedBalance}`
96+
}
97+
})()}
98+
</Paragraph>
99+
<InvestmentsAggregate />
100+
</>
101+
) : (
102+
<InvestmentsPreview />
103+
)}
104+
</Card.Footer>
94105
</Card>
95106
)
96107
}
97108

109+
function InvestmentsPreview() {
110+
const { investmentCoins, isLoading } = useCoins()
111+
112+
if (isLoading) return <Spinner size="small" />
113+
114+
const existingSymbols = new Set(investmentCoins.map((coin) => coin.symbol))
115+
const coins = [
116+
...investmentCoins,
117+
...investmentCoinsList
118+
.filter((coin) => !existingSymbols.has(coin.symbol))
119+
.map((coin) => ({ ...coin, balance: 0n })),
120+
]
121+
122+
const sortedByBalance = coins.toSorted((a, b) =>
123+
(b?.balance ?? 0n) > (a?.balance ?? 0n) ? 1 : -1
124+
)
125+
return (
126+
<XStack ai="center" jc="space-between">
127+
<OverlappingCoinIcons coins={sortedByBalance} />
128+
<Card circular ai="center" jc="center" bc="$color0" w={'$3.5'} h="$3.5" mih={0} miw={0}>
129+
<Paragraph fontSize={'$4'} fontWeight="500">
130+
{`+${investmentCoinsList.length - 3}`}
131+
</Paragraph>
132+
</Card>
133+
</XStack>
134+
)
135+
}
136+
137+
function OverlappingCoinIcons({
138+
coins,
139+
length = 3,
140+
...props
141+
}: { coins: CoinWithBalance[]; length?: number } & XStackProps) {
142+
return (
143+
<XStack ai="center" {...props}>
144+
{coins.slice(0, length).map(({ symbol }) => (
145+
<Card key={symbol} circular mr={'$-5'} bc="transparent" ai="center" jc="center">
146+
<IconCoin size={'$3'} symbol={symbol} />
147+
</Card>
148+
))}
149+
</XStack>
150+
)
151+
}
152+
98153
function InvestmentsAggregate() {
99154
const tokenIds = useCoins()
100155
.investmentCoins.filter((c) => c?.balance && c.balance > 0n)

0 commit comments

Comments
 (0)