Skip to content

Commit f0885b1

Browse files
authored
Merge pull request #1854 from IndexCoop/feat/trade-quick-stats-redesign
feat: quick stats redesign
2 parents 6173d78 + 07f182d commit f0885b1

26 files changed

+420
-298
lines changed

src/app/leverage/components/leverage-feedback-button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export function LeverageFeedbackButton() {
66
return (
77
<PopupButton
88
id='Ns10DhMF'
9-
className='text-ic-black bg-ic-gray-700 hover:bg-ic-gray-500 hidden h-12 w-full rounded-lg py-2.5 font-bold lg:block'
9+
className='hover:text-ic-white hidden h-12 w-full rounded-3xl bg-zinc-800 py-2.5 font-semibold text-neutral-400 transition hover:bg-zinc-700 lg:block'
1010
tracking={surveyTracking}
1111
>
1212
Give us your feedback!

src/app/leverage/components/leverage-panel/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,20 @@ import { Suspense } from 'react'
33
import { LeverageFeedbackButton } from '@/app/leverage/components/leverage-feedback-button'
44
import { LeverageWidget } from '@/app/leverage/components/leverage-widget'
55
import PortfolioWidget from '@/app/leverage/components/portfolio-widget/portfolio-widget'
6+
import { QuickStats } from '@/app/leverage/components/stats'
67
import { TradingViewChart } from '@/app/leverage/components/trading-view-chart'
78

89
export function LeveragePanel() {
910
return (
1011
<div className='flex flex-col gap-4 lg:flex-row'>
11-
<div className='w-full lg:flex lg:aspect-auto lg:basis-2/3 lg:flex-col lg:gap-4'>
12+
<div className='flex w-full flex-col gap-4 lg:w-2/3'>
13+
<QuickStats />
1214
<TradingViewChart />
1315
<div className='hidden lg:block lg:pt-4'>
1416
<PortfolioWidget />
1517
</div>
1618
</div>
17-
<div className='flex w-full lg:w-auto lg:basis-1/3 lg:flex-col lg:gap-4'>
19+
<div className='flex w-full lg:w-1/3 lg:flex-col lg:gap-4'>
1820
<Suspense>
1921
<LeverageWidget />
2022
</Suspense>

src/app/leverage/components/leverage-widget/components/buy-sell-selector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export function BuySellSelector({ isMinting, onClick }: BuySellSelectorProps) {
2626
return (
2727
<div
2828
ref={wrapperRef}
29-
className='bg-ic-gray-50 dark:bg-ic-gray-975 flex flex-row rounded-lg'
29+
className='bg-ic-gray-50 flex flex-row rounded-full dark:bg-zinc-800'
3030
>
3131
<BuySellSelectorButton
3232
isSelected={isMinting}

src/app/leverage/components/leverage-widget/components/leverage-selector.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import clsx from 'clsx'
2-
31
import { LeverageType } from '@/app/leverage/types'
42
import { useAnalytics } from '@/lib/hooks/use-analytics'
3+
import { cn } from '@/lib/utils/tailwind'
54

65
type LeverageSelectorProps = {
76
selectedTye: LeverageType
@@ -22,8 +21,8 @@ export function LeverageSelector(props: LeverageSelectorProps) {
2221
}
2322

2423
return (
25-
<div className='dark:border-ic-gray-700 flex flex-row items-center justify-between rounded-lg border border-[#3A6060] p-4'>
26-
<div className='text-ic-gray-300 text-xs font-medium'>Leverage</div>
24+
<div className='flex flex-row items-center justify-between rounded-lg border border-[#3A6060] p-4 dark:border-neutral-700'>
25+
<div className='text-xs font-medium text-neutral-400'>Leverage</div>
2726
<div className='flex flex-row gap-2'>
2827
{supportedTypes?.length > 0 &&
2928
supportedTypes.map((leverageType) => {
@@ -55,11 +54,11 @@ export function LeverageSelectorButton({
5554
}: LeverageSelectorButtonProps) {
5655
return (
5756
<div
58-
className={clsx(
59-
'text-ic-gray-300 bg-ic-gray-975 w-14 cursor-pointer rounded-full border px-3 py-2 text-center text-sm font-bold transition duration-150',
57+
className={cn(
58+
'w-14 cursor-pointer rounded-full border bg-zinc-800 px-3 py-2 text-center text-sm font-semibold text-neutral-400 transition duration-150',
6059
isSelected
61-
? 'border-ic-blue-600'
62-
: 'border-ic-gray-975 hover:text-ic-blue-300',
60+
? 'border-ic-blue-300 text-ic-white bg-zinc-700'
61+
: 'hover:text-ic-white border-zinc-900',
6362
)}
6463
onClick={onClick}
6564
>

src/app/leverage/components/leverage-widget/components/summary.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type SummaryQuoteProps = {
1414

1515
function SummaryQuote(props: SummaryQuoteProps) {
1616
return (
17-
<div className='text-ic-gray-300 flex flex-row items-center justify-between text-xs'>
17+
<div className='flex flex-row items-center justify-between text-xs text-neutral-400'>
1818
<div className='font-medium'>{props.label}</div>
1919
<div className='flex flex-row gap-1'>
2020
<div className='text-ic-white font-bold'>{props.value}</div>
@@ -42,11 +42,11 @@ export function Summary() {
4242

4343
if (!shouldShowSummaryDetails && !isFetchingQuote) return null
4444
return (
45-
<Disclosure as='div' className='rounded-xl border border-[#3A6060]'>
45+
<Disclosure as='div' className='rounded-lg border border-neutral-700'>
4646
{({ open }) => (
4747
<div className='p-4'>
4848
<dt>
49-
<Disclosure.Button className='text-ic-gray-300 flex w-full items-center justify-between text-left'>
49+
<Disclosure.Button className='flex w-full items-center justify-between text-left text-neutral-400'>
5050
<span className='text-xs font-medium'>
5151
{open && 'Summary'}
5252
{!open && isFetchingQuote && <StyledSkeleton width={120} />}
@@ -59,7 +59,7 @@ export function Summary() {
5959
{!open && !isFetchingQuote ? (
6060
<GasFees
6161
valueUsd={gasFeesUsd}
62-
styles={{ valueUsdTextColor: 'text-ic-gray-300' }}
62+
styles={{ valueUsdTextColor: 'text-neutral-400' }}
6363
/>
6464
) : null}
6565
{!open && isFetchingQuote && <StyledSkeleton width={70} />}
@@ -96,7 +96,7 @@ export function Summary() {
9696
value={orderFee}
9797
valueUsd={`(${orderFeePercent}%)`}
9898
/>
99-
<div className='text-ic-gray-300 flex flex-row items-center justify-between text-xs'>
99+
<div className='flex flex-row items-center justify-between text-xs text-neutral-400'>
100100
<div className='font-normal'>Network Fee</div>
101101
<div>
102102
<GasFees valueUsd={gasFeesUsd} value={gasFeesEth} />

src/app/leverage/components/leverage-widget/index.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import { useAtom } from 'jotai'
44
import { useCallback, useEffect } from 'react'
55

6+
import { TradeInputSelector } from '@/app/leverage/components/leverage-widget/trade-input-selector'
67
import { supportedNetworks } from '@/app/leverage/constants'
78
import { useLeverageToken } from '@/app/leverage/provider'
89
import { tradeMachineAtom } from '@/app/store/trade-machine'
910
import { Receive } from '@/components/receive'
1011
import { Settings } from '@/components/settings'
1112
import { SmartTradeButton } from '@/components/smart-trade-button'
1213
import { SelectTokenModal } from '@/components/swap/components/select-token-modal'
13-
import { TradeInputSelector } from '@/components/swap/components/trade-input-selector'
1414
import { TransactionReviewModal } from '@/components/swap/components/transaction-review'
1515
import { WarningType } from '@/components/swap/components/warning'
1616
import { TradeButtonState } from '@/components/swap/hooks/use-trade-button-state'
@@ -29,8 +29,6 @@ import { BuySellSelector } from './components/buy-sell-selector'
2929
import { LeverageSelector } from './components/leverage-selector'
3030
import { Summary } from './components/summary'
3131

32-
import './styles.css'
33-
3432
const hiddenLeverageWarnings = [WarningType.flashbots]
3533

3634
export function LeverageWidget() {
@@ -103,7 +101,7 @@ export function LeverageWidget() {
103101

104102
return (
105103
<div
106-
className='leverage-widget flex w-full flex-col gap-4 rounded-lg px-4 pb-5 pt-4'
104+
className='flex w-full flex-col gap-4 rounded-lg border border-white/15 bg-zinc-900 px-4 pb-5 pt-4'
107105
id='close-position-scroll'
108106
>
109107
<BuySellSelector isMinting={isMinting} onClick={toggleIsMinting} />

src/app/leverage/components/leverage-widget/styles.css

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { Flex, Input, Text } from '@chakra-ui/react'
2+
3+
import { Caption } from '@/components/swap/components/caption'
4+
import { SelectorButton } from '@/components/swap/components/selector-button'
5+
import { colors } from '@/lib/styles/colors'
6+
import { cn } from '@/lib/utils/tailwind'
7+
8+
export type InputSelectorToken = {
9+
decimals: number
10+
image: string
11+
symbol: string
12+
}
13+
14+
interface TradeInputSelectorConfig {
15+
isInputDisabled?: boolean
16+
isReadOnly?: boolean
17+
isSelectorDisabled?: boolean
18+
}
19+
interface TradeInputSelectorProps {
20+
config: TradeInputSelectorConfig
21+
caption: string
22+
balance: string
23+
formattedFiat: string
24+
selectedToken: InputSelectorToken
25+
selectedTokenAmount: string
26+
priceImpact?: { colorCoding: string; value: string }
27+
showSelectorButtonChevron?: boolean
28+
showSelectorButton?: boolean
29+
onSelectToken: () => void
30+
onChangeInput?: (token: InputSelectorToken, amount: string) => void
31+
onClickBalance?: () => void
32+
}
33+
34+
export const TradeInputSelector = (props: TradeInputSelectorProps) => {
35+
const {
36+
balance,
37+
config,
38+
formattedFiat,
39+
selectedToken,
40+
showSelectorButton = true,
41+
} = props
42+
43+
const onChangeInput = (amount: string) => {
44+
if (
45+
props.onChangeInput === undefined ||
46+
config.isInputDisabled === true ||
47+
config.isSelectorDisabled === true ||
48+
config.isReadOnly === true
49+
)
50+
return
51+
props.onChangeInput(selectedToken, amount)
52+
}
53+
54+
return (
55+
<div className='bg-ic-white border-ic-gray-100 flex flex-col rounded-lg border px-4 py-5 dark:border-[#D4D4D4] dark:bg-zinc-800'>
56+
<Caption caption={props.caption} />
57+
<Flex align='center' direction='row' justify='space-between' mt='6px'>
58+
{config.isReadOnly ? (
59+
<p
60+
className={cn(
61+
'text-ellipsis whitespace-nowrap pr-1 text-[25px] font-medium',
62+
props.selectedTokenAmount === '0'
63+
? 'text-ic-gray-400'
64+
: 'text-ic-black',
65+
)}
66+
>
67+
{props.selectedTokenAmount}
68+
</p>
69+
) : (
70+
<Input
71+
className='text-ic-black dark:text-ic-white bg-transparent pr-1 text-3xl'
72+
fontSize='25px'
73+
fontWeight={500}
74+
overflow='hidden'
75+
placeholder='0'
76+
_placeholder={{ color: colors.ic.gray[400] }}
77+
type='number'
78+
onWheel={(e) => e.target instanceof HTMLElement && e.target.blur()}
79+
step='any'
80+
textOverflow='ellipsis'
81+
variant='unstyled'
82+
whiteSpace='nowrap'
83+
disabled={config.isInputDisabled ?? false}
84+
isReadOnly={config.isReadOnly ?? false}
85+
value={props.selectedTokenAmount}
86+
onChange={(event) => {
87+
onChangeInput(event.target.value)
88+
}}
89+
/>
90+
)}
91+
<SelectorButton
92+
image={selectedToken.image}
93+
symbol={selectedToken.symbol}
94+
showChevron={props.showSelectorButtonChevron}
95+
visible={showSelectorButton}
96+
onClick={props.onSelectToken}
97+
/>
98+
</Flex>
99+
<Flex
100+
align='flex-start'
101+
direction='row'
102+
justify='space-between'
103+
mt='10px'
104+
>
105+
<PriceUsd fiat={formattedFiat} priceImpact={props.priceImpact} />
106+
{showSelectorButton ? (
107+
<Balance balance={balance} onClick={props.onClickBalance} />
108+
) : null}
109+
</Flex>
110+
</div>
111+
)
112+
}
113+
114+
interface BalanceProps {
115+
balance: string
116+
onClick?: () => void
117+
}
118+
119+
const Balance = ({ balance, onClick }: BalanceProps) => {
120+
const showMaxLabel = onClick !== undefined
121+
return (
122+
<div
123+
className='flex cursor-pointer flex-row items-center gap-2'
124+
onClick={onClick}
125+
>
126+
<div className='text-ic-gray-400 text-xs font-medium dark:text-neutral-400'>
127+
Balance: {balance}
128+
</div>
129+
{showMaxLabel && (
130+
<div className='bg-ic-blue-500 dark:bg-ic-blue-300 align-center justify-center rounded-xl px-2 py-[2px]'>
131+
<div className='text-ic-white text-[9px] font-medium dark:text-zinc-900'>
132+
Max
133+
</div>
134+
</div>
135+
)}
136+
</div>
137+
)
138+
}
139+
140+
interface PriceUsdProps {
141+
fiat: string
142+
priceImpact?: {
143+
colorCoding: string
144+
value: string
145+
}
146+
}
147+
148+
const PriceUsd = (props: PriceUsdProps) => (
149+
<Flex>
150+
<p className='text-xs font-medium text-neutral-400'>{props.fiat}</p>
151+
{props.priceImpact && (
152+
<Text fontSize='12px' textColor={props.priceImpact.colorCoding}>
153+
&nbsp;{props.priceImpact.value}
154+
</Text>
155+
)}
156+
</Flex>
157+
)

src/app/leverage/components/portfolio-widget/portfolio-widget.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,16 +136,16 @@ const OpenPositions = () => {
136136
selectedIndex={selectedIndex}
137137
onChange={setSelectedIndex}
138138
>
139-
<TabList className='text-ic-gray-600 flex gap-6 text-sm font-bold'>
139+
<TabList className='flex gap-6 text-sm font-bold text-neutral-400'>
140140
<Tab
141-
className='data-[selected]:text-ic-gray-50 flex items-center gap-2 outline-none'
141+
className='flex items-center gap-2 outline-none data-[selected]:text-neutral-50'
142142
onClick={() => logEvent('Open Positions Tab Clicked')}
143143
>
144144
Open Positions
145145
<span
146146
className={cn(
147147
'text-ic-gray-300 flex h-3.5 items-center justify-center rounded-[4px] bg-purple-500/30 px-1.5 py-0.5 text-[8px]',
148-
selectedIndex === 0 && 'text-ic-white bg-purple-500',
148+
selectedIndex === 0 && 'bg-purple-500 text-neutral-50',
149149
)}
150150
>
151151
BETA

src/app/leverage/components/portfolio-widget/table.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ export const TableRenderer = ({ table, emptyText, isFetching }: TableProps) => {
4949
))}
5050
</div>
5151
) : table.getRowModel().rows.length === 0 ? (
52-
<div className='text-ic-white t text-md flex w-full items-center justify-center rounded-lg bg-[#1A2A2B] px-4 py-3 text-sm font-semibold'>
52+
<div className='text-ic-white t text-md flex w-full items-center justify-center rounded-lg bg-zinc-900 px-4 py-3 text-sm font-semibold'>
5353
{emptyText}
5454
</div>
5555
) : (
5656
table.getRowModel().rows.map((row) => (
5757
<div
58-
className='text-ic-white flex w-full items-center rounded-lg bg-[#1A2A2B] px-4 py-3 text-left text-xs'
58+
className='text-ic-white flex w-full items-center rounded-lg bg-zinc-900 px-4 py-3 text-left text-xs'
5959
key={row.id}
6060
>
6161
{row.getVisibleCells().map((cell) => (

0 commit comments

Comments
 (0)