Skip to content

Commit

Permalink
feat: add trading buttons and deposit disclosure
Browse files Browse the repository at this point in the history
  • Loading branch information
Yavorski committed Feb 26, 2024
1 parent 3c9ba4d commit 8deebec
Show file tree
Hide file tree
Showing 20 changed files with 527 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export const ActionButton: FC<PropsWithChildren<ActionButtonProps>> = ({
'dtw-duration-500',
'dtw-ease-in-out',
'disabled:dtw-opacity-50',
'dtw-py-2',
'dtw-px-5',
{
[HIGHLIGHTED_CLASSNAMES.join(' ')]: highlighted,
[NON_HIGHLIGHTED_CLASSNAMES.join(' ')]: !highlighted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ChevronDownIcon } from '@heroicons/react/24/solid'
import classNames from 'classnames'
import type { FC, PropsWithChildren } from 'react'

import { useTranslationContext } from 'providers/translation-provider'

import { THEME_TYPE } from 'types'
import type { ThemeType } from 'types'

Expand All @@ -23,48 +25,52 @@ export const TransactionOverviewDisclosure: FC<
staticItems,
collapseItems,
themeType = THEME_TYPE.DEFAULT,
}) => (
<div className="dtw-w-full dtw-flex dtw-flex-col dtw-gap-1">
<Disclosure>
{({ open }) => (
<>
{staticItems?.map((props) => (
<TransactionDisclosureItem key={props.label} {...props} />
))}
<Disclosure.Button className="dtw-flex dtw-w-full dtw-justify-between dtw-rounded-[var(--panel-radius-secondary,var(--panel-radius))] hover:dtw-bg-[var(--panel-meta-hover-bg,var(--panel-neutral-color))] focus:dtw-outline-none">
<TransactionDisclosureItem
tooltipText="See full details influencing what you will recieve."
label="Trade details"
value=""
type={themeType}
}) => {
const t = useTranslationContext()

return (
<div className="dtw-w-full dtw-flex dtw-flex-col dtw-gap-1">
<Disclosure>
{({ open }) => (
<>
{staticItems?.map((props) => (
<TransactionDisclosureItem key={props.label} {...props} />
))}
<Disclosure.Button className="dtw-flex dtw-w-full dtw-justify-between dtw-rounded-[var(--panel-radius-secondary,var(--panel-radius))] hover:dtw-bg-[var(--panel-meta-hover-bg,var(--panel-neutral-color))] focus:dtw-outline-none">
<TransactionDisclosureItem
tooltipText={t.fullReceiveDetails}
label={t.tradeDetails}
value=""
type={themeType}
>
<ExchangeRate />
<ChevronDownIcon
className={classNames(
'dtw-text-[color:var(--panel-icon-color,var(--panel-content-color))] dtw-h-[var(--panel-input-token-icon-size,var(--panel-icon-size))] dtw-w-[var(--panel-input-token-icon-size,var(--panel-icon-size))] sm:dtw-w-[var(--panel-input-token-icon-size-sm,var(--panel-icon-size-sm))] sm:dtw-h-[var(--panel-input-token-icon-size-sm,var(--panel-icon-size-sm))]',
{ 'dtw-rotate-180 dtw-transform': open },
)}
/>
</TransactionDisclosureItem>
</Disclosure.Button>
<Transition
show={open}
enter="dtw-transition dtw-duration-100 dtw-ease-out"
enterFrom="dtw-transform dtw-scale-95 dtw-opacity-0"
enterTo="dtw-transform dtw-scale-100 dtw-opacity-100"
leave="dtw-transition dtw-duration-75 dtw-ease-out"
leaveFrom="dtw-transform dtw-scale-100 dtw-opacity-100"
leaveTo="dtw-transform dtw-scale-95 dtw-opacity-0"
>
<ExchangeRate />
<ChevronDownIcon
className={classNames(
'dtw-text-[color:var(--panel-icon-color,var(--panel-content-color))] dtw-h-[var(--panel-input-token-icon-size,var(--panel-icon-size))] dtw-w-[var(--panel-input-token-icon-size,var(--panel-icon-size))] sm:dtw-w-[var(--panel-input-token-icon-size-sm,var(--panel-icon-size-sm))] sm:dtw-h-[var(--panel-input-token-icon-size-sm,var(--panel-icon-size-sm))]',
{ 'dtw-rotate-180 dtw-transform': open },
)}
/>
</TransactionDisclosureItem>
</Disclosure.Button>
<Transition
show={open}
enter="dtw-transition dtw-duration-100 dtw-ease-out"
enterFrom="dtw-transform dtw-scale-95 dtw-opacity-0"
enterTo="dtw-transform dtw-scale-100 dtw-opacity-100"
leave="dtw-transition dtw-duration-75 dtw-ease-out"
leaveFrom="dtw-transform dtw-scale-100 dtw-opacity-100"
leaveTo="dtw-transform dtw-scale-95 dtw-opacity-0"
>
<Disclosure.Panel className="dtw-static dtw-text-[length:var(--panel-label-font-size,var(--panel-font-size-xs))] dtw-leading-[var(--panel-label-line-height,var(--panel-line-height-xs))] dtw-text-[color:var(--panel-secondary-content-color)] dtw-font-[var(--panel-meta-font-weight,var(--panel-font-weight-light))] dtw-rounded-[var(--panel-radius-secondary,var(--panel-radius))] dtw-flex dtw-flex-col dtw-gap-1">
{collapseItems?.map((props) => (
<TransactionDisclosureItem key={props.label} {...props} />
))}
{children}
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
</div>
)
<Disclosure.Panel className="dtw-static dtw-text-[length:var(--panel-label-font-size,var(--panel-font-size-xs))] dtw-leading-[var(--panel-label-line-height,var(--panel-line-height-xs))] dtw-text-[color:var(--panel-secondary-content-color)] dtw-font-[var(--panel-meta-font-weight,var(--panel-font-weight-light))] dtw-rounded-[var(--panel-radius-secondary,var(--panel-radius))] dtw-flex dtw-flex-col dtw-gap-1">
{collapseItems?.map((props) => (
<TransactionDisclosureItem key={props.label} {...props} />
))}
{children}
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useHandleTrade } from '@dhedge/core-ui-kit/hooks/trading'
import { useDeposit } from '@dhedge/core-ui-kit/hooks/trading/deposit'
import type { FC } from 'react'

import { ActionButton } from 'components/common'

export const DepositTradeButton: FC = () => {
const deposit = useDeposit()
const { disabled, label, handleTrade } = useHandleTrade(deposit)

return (
<ActionButton onClick={handleTrade} disabled={disabled} highlighted>
{label}
</ActionButton>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const useValidDepositButton = () => {
const { shouldBeWhitelisted, isAccountWhitelisted } = useShouldBeWhitelisted()
const poolTokenPrice = usePoolTokenPrice({ address, chainId })
const { minDepositUSD } = usePoolManagerLogicData(address, chainId)
const { userBalance, tokenPrice } = usePoolDynamicContractData({
const { userBalance } = usePoolDynamicContractData({
address,
chainId,
})
Expand All @@ -43,7 +43,7 @@ export const useValidDepositButton = () => {
).multipliedBy(poolTokenPrice || '0')

const poolBalanceInUsdNumber =
normalizeNumber(userBalance ?? 0) * normalizeNumber(tokenPrice ?? 0)
normalizeNumber(userBalance ?? 0) * normalizeNumber(poolTokenPrice ?? 0)

const isLowerThanMinDeposit =
poolBalanceInUsdNumber < minDepositUSD ||
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {
usePoolFees,
usePoolManagerLogicData,
} from '@dhedge/core-ui-kit/hooks/pool'
import {
useReceiveTokenInput,
useSendTokenInput,
useTradingPanelApprovingStatus,
useTradingPanelLockTime,
useTradingPanelPoolConfig,
useTradingPanelSettings,
} from '@dhedge/core-ui-kit/hooks/state'
import { useProjectedEarnings } from '@dhedge/core-ui-kit/hooks/trading/deposit'
import { formatToUsd } from '@dhedge/core-ui-kit/utils'
import BigNumber from 'bignumber.js'

import { useGetSlippagePlaceholder, useGetThemeTypeBySlippage } from 'hooks'
import { useConfigContextParams } from 'providers/config-provider'
import { useTranslationContext } from 'providers/translation-provider'

import { THEME_TYPE } from 'types'

export const useDepositTransactionDisclosure = () => {
const t = useTranslationContext()
const { customLockTime } = useConfigContextParams()
const [approvingStatus] = useTradingPanelApprovingStatus()
const [{ slippage, minSlippage, isInfiniteAllowance, isMaxSlippageLoading }] =
useTradingPanelSettings()
const [receiveToken] = useReceiveTokenInput()
const [sendToken] = useSendTokenInput()
const { address, chainId } = useTradingPanelPoolConfig()

const { entryFee, hasPoolEntryFee } = usePoolFees({ address, chainId })
const { minDepositUSD } = usePoolManagerLogicData(address, chainId)
const projectedEarnings = useProjectedEarnings()
const lockTime = useTradingPanelLockTime()

const minDeposit = minDepositUSD
? formatToUsd({ value: minDepositUSD, minimumFractionDigits: 0 })
: ''

const isAutoSlippage = slippage === 'auto'

const themeType = useGetThemeTypeBySlippage(
isAutoSlippage ? minSlippage ?? 0 : slippage,
)

const slippagePlaceholder = useGetSlippagePlaceholder(
'deposit',
slippage,
minSlippage,
)
const slippageTooltipText =
themeType === THEME_TYPE.DEFAULT ? t.slippageWarning : t.highSlippageWarning

const getMinReceiveText = () => {
if (isAutoSlippage) {
return `${new BigNumber(receiveToken.value ?? 0).toFixed(
4,
)} ${receiveToken.symbol.toUpperCase()}`
}
if (receiveToken.symbol === 'all') {
return t.estimatedMultiAssetFractions
}

const receiveBalance = new BigNumber(receiveToken.value ?? 0)
const receiveValueAfterSlippage =
receiveToken.value && receiveBalance.isFinite()
? receiveBalance.times(1 - slippage / 100).toFixed(4)
: '0'

return `${receiveValueAfterSlippage} ${receiveToken.symbol.toUpperCase()}`
}

const tokenAllowance = isInfiniteAllowance
? t.infinite
: `${new BigNumber(sendToken.value || '0').toFixed(4)} ${sendToken.symbol}`

const entryFeeTooltipText = hasPoolEntryFee
? t.entryFeeExplanation
: t.easySwapperEntryFee.replace('{time}', customLockTime)

return {
projectedEarnings,
themeType,
slippageTooltipText,
isMaxSlippageLoading,
slippagePlaceholder,
minReceive: getMinReceiveText(),
allowanceRequired: !approvingStatus,
tokenAllowance,
sendTokenSymbol: sendToken.symbol,
entryFee,
entryFeeTooltipText,
minDeposit,
lockTime,
}
}
Original file line number Diff line number Diff line change
@@ -1,38 +1,125 @@
import classNames from 'classnames'

import { useMemo } from 'react'

import type { TransactionDisclosureItemProps } from 'components/common'
import { TransactionOverviewDisclosure } from 'components/common'
import { Spinner, TransactionOverviewDisclosure } from 'components/common'
import { useTranslationContext } from 'providers/translation-provider'

import { THEME_TYPE } from 'types'

import { useDepositTransactionDisclosure } from './transaction-disclosure.hooks'

export const DepositTransactionOverviewDisclosure = () => {
const staticItems = useMemo<TransactionDisclosureItemProps[]>(
() => [
const t = useTranslationContext()
const {
projectedEarnings: { yearlyEarnings, dailyEarnings },
slippageTooltipText,
slippagePlaceholder,
isMaxSlippageLoading,
minReceive,
themeType,
allowanceRequired,
tokenAllowance,
sendTokenSymbol,
entryFee,
entryFeeTooltipText,
minDeposit,
lockTime,
} = useDepositTransactionDisclosure()

const staticItems: TransactionDisclosureItemProps[] = [
{
tooltipText: t.projectedDailyEarningsTooltip,
label: t.dailyEarnings,
value: dailyEarnings,
emphasised: true,
},
{
tooltipText: t.projectedYearlyEarningsTooltip,
label: t.yearlyEarnings,
value: yearlyEarnings,
emphasised: true,
},
]

const collapseItems = useMemo<TransactionDisclosureItemProps[]>(() => {
const items: TransactionDisclosureItemProps[] = [
{
tooltipText: 'Deposit static tooltip text',
label: 'Deposit static label',
value: 'Deposit static value',
emphasised: true,
tooltipText: slippageTooltipText,
label: t.maxSlippage,
value: (
<div className="dtw-flex dtw-gap-1">
{isMaxSlippageLoading && (
<Spinner
type={THEME_TYPE.CUSTOM}
className="dtw-stroke-[color:var(--panel-accent-from-color)] dtw-h-[var(--panel-icon-secondary-size)] sm:dtw-h-[var(--panel-icon-secondary-size-sm)] dtw-w-[var(--panel-icon-secondary-size)] sm:dtw-w-[var(--panel-icon-secondary-size-sm)]"
/>
)}
<span
className={classNames({
'dtw-text-[color:var(--panel-loading-content-color)]':
isMaxSlippageLoading,
})}
>
{slippagePlaceholder}%
</span>
</div>
),
},
],
[],
)

const collapseItems = useMemo<TransactionDisclosureItemProps[]>(
() => [
{
tooltipText: 'Deposit collapse tooltip text',
label: 'Deposit collapse label',
value: 'Deposit collapse value',
tooltipText: t.minReceiveAmount,
label: t.minReceived,
value: minReceive,
},
],
[],
)
]

if (allowanceRequired) {
items.push({
tooltipText: t.amountToBeApproved.replace('{symbol}', sendTokenSymbol),
label: t.tokenAllowance,
value: tokenAllowance,
})
}

items.push({
tooltipText: entryFeeTooltipText,
label: t.entryFee,
value: entryFee,
})

if (minDeposit) {
items.push({
tooltipText: t.minDepositUsd,
label: t.minDeposit,
value: minDeposit,
})
}

return items
}, [
slippageTooltipText,
t,
isMaxSlippageLoading,
slippagePlaceholder,
minReceive,
allowanceRequired,
sendTokenSymbol,
tokenAllowance,
entryFeeTooltipText,
entryFee,
minDeposit,
])

return (
<TransactionOverviewDisclosure
staticItems={staticItems}
collapseItems={collapseItems}
themeType={themeType}
>
Deposit TransactionOverviewDisclosure Children
<p className="dtw-py-1">
{t.tokensLockTime.replace('{lockTime}', lockTime)}
</p>
</TransactionOverviewDisclosure>
)
}
Loading

0 comments on commit 8deebec

Please sign in to comment.